//////////////////////////////////////////////////////////////////////////
public:
	/// <summary>
	/// Copies source 2D array inside of the larger destination array and
	/// makes a border of the specified type (IPL_BORDER_*) around the copied area.
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="offset"></param>
	/// <param name="bordertype"></param>
	static void CopyMakeBorder(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32s offset, ImageBorder bordertype, NAMESPACE::Scalar value)
	{
		cvCopyMakeBorder(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint*)&offset, (int)bordertype, *(CvScalar*)&value);
	}

	/// <summary>
	/// Copies source 2D array inside of the larger destination array and
	/// makes a border of the specified type (IPL_BORDER_*) around the copied area.
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="offset"></param>
	static void CopyMakeBorder(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32s offset, ImageBorder bordertype)
	{
		cvCopyMakeBorder(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint*)&offset, (int)bordertype);
	}

	/// <summary>
	/// Smooths the image in one of several ways.
	/// The function cvSmooth smooths an image using one of several methods. Every of the methods
	/// has some features and restrictions listed below
	///	Blur with no scaling works with single-channel images only and supports accumulation of 8-bit
	///	to 16-bit format (similar to Sobel and Laplace ) and 32-bit floating point to 32-bit floating-point
	///	format.
	///	Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images.
	///	These two methods can process images in-place.
	///	Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images
	///	in-place.
	/// </summary>
	/// <param name="src">The source image</param>
	/// <param name="dst">The destination image</param>
	/// <param name="smoothtype">Type of the smoothing</param>
	/// <param name="size1">The first parameter of the smoothing operation</param>
	/// <param name="size2">The second parameter of the smoothing operation. In the case of simple scaled/nonscaled
	/// and Gaussian blur if param2 is zero, it is set to param1</param>
	/// <param name="sigma1"></param>
	/// <param name="sigma2"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst, SmoothType smoothtype, int size1, int size2, double sigma1, double sigma2)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)smoothtype, size1, size2, sigma1, sigma2);
	}

	/// <summary>
	/// Smoothes array (removes noise)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="smoothtype"></param>
	/// <param name="size1"></param>
	/// <param name="size2"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst, SmoothType smoothtype, int size1, int size2, double sigma1)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)smoothtype, size1, size2, sigma1);
	}

	/// <summary>
	/// Smoothes array (removes noise)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="smoothtype"></param>
	/// <param name="size1"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst, SmoothType smoothtype, int size1, int size2)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)smoothtype, size1, size2);
	}

	/// <summary>
	/// Smoothes array (removes noise)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="smoothtype"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst, SmoothType smoothtype, int size1)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)smoothtype, size1);
	}

	/// <summary>
	/// Smoothes array (removes noise)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst, SmoothType smoothtype)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)smoothtype);
	}

	/// <summary>
	/// Smoothes array (removes noise)
	/// </summary>
	/// <param name="src"></param>
	static void Smooth(ManagedArr^ src, ManagedArr^ dst)
	{
		cvSmooth(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Convolves the image with the kernel
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="kernel"></param>
	static void Filter2D(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ kernel, NAMESPACE::Point2D32s anchor)
	{
		cvFilter2D(src->ToCvArrPointer(), dst->ToCvArrPointer(), kernel->ToCvMatPointer(), *(CvPoint*)&anchor);
	}

	/// <summary>
	/// Convolves the image with the kernel
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Filter2D(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ kernel)
	{
		cvFilter2D(src->ToCvArrPointer(), dst->ToCvArrPointer(), kernel->ToCvMatPointer());
	}

	/// <summary>
	/// Finds integral image: SUM(X,Y) = sum(x<X,y<Y)I(x,y)
	/// </summary>
	/// <param name="image"></param>
	/// <param name="sum"></param>
	/// <param name="sqsum"></param>
	static void Integral(ManagedArr^ image, ManagedArr^ sum, ManagedArr^ sqsum, ManagedArr^ tilted_sum)
	{
		cvIntegral(image->ToCvArrPointer(), sum->ToCvArrPointer(), sqsum->ToCvArrPointer(), tilted_sum->ToCvArrPointer());
	}

	/// <summary>
	/// Finds integral image: SUM(X,Y) = sum(x<X,y<Y)I(x,y)
	/// </summary>
	/// <param name="image"></param>
	/// <param name="sum"></param>
	static void Integral(ManagedArr^ image, ManagedArr^ sum, ManagedArr^ sqsum)
	{
		cvIntegral(image->ToCvArrPointer(), sum->ToCvArrPointer(), sqsum->ToCvArrPointer());
	}

	/// <summary>
	/// Finds integral image: SUM(X,Y) = sum(x<X,y<Y)I(x,y)
	/// </summary>
	/// <param name="image"></param>
	static void Integral(ManagedArr^ image, ManagedArr^ sum)
	{
		cvIntegral(image->ToCvArrPointer(), sum->ToCvArrPointer());
	}

	/// <summary>
	/// Smoothes the input image with gaussian kernel and then down-samples it.
	/// dst_width = floor(src_width/2)[+1],
	/// dst_height = floor(src_height/2)[+1]
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void PyrDown(ManagedArr^ src, ManagedArr^ dst, FilterType filter)
	{
		cvPyrDown(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)filter);
	}

	/// <summary>
	/// Smoothes the input image with gaussian kernel and then down-samples it.
	/// dst_width = floor(src_width/2)[+1],
	/// dst_height = floor(src_height/2)[+1]
	/// </summary>
	/// <param name="src"></param>
	static void PyrDown(ManagedArr^ src, ManagedArr^ dst)
	{
		cvPyrDown(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Up-samples image and smoothes the result with gaussian kernel.
	/// dst_width = src_width*2,
	/// dst_height = src_height*2
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void PyrUp(ManagedArr^ src, ManagedArr^ dst, FilterType filter)
	{
		cvPyrUp(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)filter);
	}

	/// <summary>
	/// Up-samples image and smoothes the result with gaussian kernel.
	/// dst_width = src_width*2,
	/// dst_height = src_height*2
	/// </summary>
	/// <param name="src"></param>
	static void PyrUp(ManagedArr^ src, ManagedArr^ dst)
	{
		cvPyrUp(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Builds pyramid for an image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="extra_layers"></param>
	/// <param name="rate"></param>
	/// <param name="layer_sizes"></param>
	/// <param name="bufarr"></param>
	/// <param name="calc"></param>
	/// <returns></returns>
	static ManagedPyramid^ CreatePyramid(ManagedArr^ img, int extra_layers, double rate, array<NAMESPACE::Size2D32s>^ layer_sizes, ManagedArr^ bufarr, int calc, FilterType filter)
	{
		pin_ptr<NAMESPACE::Size2D32s> player_sizes = &layer_sizes[0];
		return gcnew ManagedPyramid(cvCreatePyramid(img->ToCvArrPointer(), extra_layers, rate, (CvSize*)player_sizes, bufarr->ToCvArrPointer(), calc, (int)filter), extra_layers, true);
	}

	/// <summary>
	/// Builds pyramid for an image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="extra_layers"></param>
	/// <param name="rate"></param>
	/// <param name="layer_sizes"></param>
	/// <param name="bufarr"></param>
	/// <returns></returns>
	static ManagedPyramid^ CreatePyramid(ManagedArr^ img, int extra_layers, double rate, array<NAMESPACE::Size2D32s>^  layer_sizes, ManagedArr^ bufarr, int calc)
	{
		pin_ptr<NAMESPACE::Size2D32s> player_sizes = &layer_sizes[0];
		return gcnew ManagedPyramid(cvCreatePyramid(img->ToCvArrPointer(), extra_layers, rate, (CvSize*)player_sizes, bufarr->ToCvArrPointer(), calc), extra_layers, true);
	}

	/// <summary>
	/// Builds pyramid for an image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="extra_layers"></param>
	/// <param name="rate"></param>
	/// <param name="layer_sizes"></param>
	/// <returns></returns>
	static ManagedPyramid^ CreatePyramid(ManagedArr^ img, int extra_layers, double rate, array<NAMESPACE::Size2D32s>^  layer_sizes, ManagedArr^ bufarr)
	{
		pin_ptr<NAMESPACE::Size2D32s> player_sizes = &layer_sizes[0];
		return gcnew ManagedPyramid(cvCreatePyramid(img->ToCvArrPointer(), extra_layers, rate, (CvSize*)player_sizes, bufarr->ToCvArrPointer()), extra_layers, true);
	}

	/// <summary>
	/// Builds pyramid for an image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="extra_layers"></param>
	/// <param name="rate"></param>
	/// <returns></returns>
	static ManagedPyramid^ CreatePyramid(ManagedArr^ img, int extra_layers, double rate, array<NAMESPACE::Size2D32s>^ layer_sizes)
	{
		pin_ptr<NAMESPACE::Size2D32s> player_sizes = &layer_sizes[0];
		return gcnew ManagedPyramid(cvCreatePyramid(img->ToCvArrPointer(), extra_layers, rate, (CvSize*)player_sizes), extra_layers, true);
	}

	/// <summary>
	/// Builds pyramid for an image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="extra_layers"></param>
	/// <returns></returns>
	static ManagedPyramid^ CreatePyramid(ManagedArr^ img, int extra_layers, double rate)
	{
		return gcnew ManagedPyramid(cvCreatePyramid(img->ToCvArrPointer(), extra_layers, rate), extra_layers, true);
	}

	/// <summary>
	/// Releases pyramid
	/// </summary>
	/// <param name="pyramid"></param>
	static void ReleasePyramid(ManagedPyramid^% pyramid, int extra_layers)
	{
		CvMat** ppMat = pyramid->ToCvMatPointerPointer();
		cvReleasePyramid(&ppMat, extra_layers);
		pyramid->m_pHandle = ppMat;
	}

	/// <summary>
	/// Splits color or grayscale image into multiple connected components
	/// of nearly the same color/brightness using modification of Burt algorithm.
	/// comp with contain a pointer to sequence (CvSeq)
	/// of connected components (CvConnectedComp)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="storage"></param>
	/// <param name="comp"></param>
	/// <param name="level"></param>
	/// <param name="threshold1"></param>
	static void PyrSegmentation(ManagedImage^ src, ManagedImage^ dst, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% comp, int level, double threshold1, double threshold2)
	{
		CvSeq* pcomp = NULL;
		cvPyrSegmentation(src->ToIplImagePointer(), dst->ToIplImagePointer(), storage->ToCvMemStoragePointer(), &pcomp, level, threshold1, threshold2);
		comp = gcnew ManagedSeq(pcomp);
	}

	/// <summary>
	/// Filters image using meanshift algorithm
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="sp"></param>
	/// <param name="sr"></param>
	/// <param name="max_level"></param>
	static void PyrMeanShiftFiltering(ManagedArr^ src, ManagedArr^ dst, double sp, double sr, int max_level, NAMESPACE::TermCriteria termcrit)
	{
		cvPyrMeanShiftFiltering(src->ToCvArrPointer(), dst->ToCvArrPointer(), sp, sr, max_level, *(CvTermCriteria*)&termcrit);
	}

	/// <summary>
	/// Filters image using meanshift algorithm
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="sp"></param>
	/// <param name="sr"></param>
	static void PyrMeanShiftFiltering(ManagedArr^ src, ManagedArr^ dst, double sp, double sr, int max_level)
	{
		cvPyrMeanShiftFiltering(src->ToCvArrPointer(), dst->ToCvArrPointer(), sp, sr, max_level);
	}

	/// <summary>
	/// Filters image using meanshift algorithm
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="sp"></param>
	static void PyrMeanShiftFiltering(ManagedArr^ src, ManagedArr^ dst, double sp, double sr)
	{
		cvPyrMeanShiftFiltering(src->ToCvArrPointer(), dst->ToCvArrPointer(), sp, sr);
	}

	/// <summary>
	/// Segments image using seed "markers"
	/// </summary>
	/// <param name="image"></param>
	static void Watershed(ManagedArr^ image, ManagedArr^ markers)
	{
		cvWatershed(image->ToCvArrPointer(), markers->ToCvArrPointer());
	}

	/// <summary>
	/// Inpaints the selected region in the image
	/// </summary>
	/// <param name="src"></param>
	/// <param name="inpaint_mask"></param>
	/// <param name="dst"></param>
	/// <param name="inpaintRange"></param>
	static void Inpaint(ManagedArr^ src, ManagedArr^ inpaint_mask, ManagedArr^ dst, double inpaintRange, InpaintType flags)
	{
		cvInpaint(src->ToCvArrPointer(), inpaint_mask->ToCvArrPointer(), dst->ToCvArrPointer(), inpaintRange, (int)flags);
	}

	/// <summary>
	/// Calculates an image derivative using generalized Sobel
	/// (aperture_size = 1,3,5,7) or Scharr (aperture_size = -1) operator.
	/// Scharr can be used only for the first dx or dy derivative
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="xorder"></param>
	/// <param name="yorder"></param>
	static void Sobel(ManagedArr^ src, ManagedArr^ dst, int xorder, int yorder, ApertureSize aperture_size)
	{
		cvSobel(src->ToCvArrPointer(), dst->ToCvArrPointer(), xorder, yorder, (int)aperture_size);
	}

	/// <summary>
	/// Calculates an image derivative using generalized Sobel
	/// (aperture_size = 1,3,5,7) or Scharr (aperture_size = -1) operator.
	/// Scharr can be used only for the first dx or dy derivative
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="xorder"></param>
	static void Sobel(ManagedArr^ src, ManagedArr^ dst, int xorder, int yorder)
	{
		cvSobel(src->ToCvArrPointer(), dst->ToCvArrPointer(), xorder, yorder);
	}

	/// <summary>
	/// Calculates the image Laplacian: (d2/dx + d2/dy)I
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Laplace(ManagedArr^ src, ManagedArr^ dst, ApertureSize aperture_size)
	{
		cvLaplace(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)aperture_size);
	}

	/// <summary>
	/// Calculates the image Laplacian: (d2/dx + d2/dy)I
	/// </summary>
	/// <param name="src"></param>
	static void Laplace(ManagedArr^ src, ManagedArr^ dst)
	{
		cvLaplace(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Converts input array pixels from one color space to another
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void CvtColor(ManagedArr^ src, ManagedArr^ dst, ColorMapType code)
	{
		cvCvtColor(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)code);
	}

	/// <summary>
	/// Resizes image (input array is resized to fit the destination array)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Resize(ManagedArr^ src, ManagedArr^ dst, TransformFlag interpolation)
	{
		cvResize(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)interpolation);
	}

	/// <summary>
	/// Resizes image (input array is resized to fit the destination array)
	/// </summary>
	/// <param name="src"></param>
	static void Resize(ManagedArr^ src, ManagedArr^ dst)
	{
		cvResize(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Warps image with affine transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="map_matrix"></param>
	/// <param name="flags"></param>
	static void WarpAffine(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix, TransformFlag flags, NAMESPACE::Scalar fillval)
	{
		cvWarpAffine(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer(), (int)flags, *(CvScalar*)&fillval);
	}

	/// <summary>
	/// Warps image with affine transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="map_matrix"></param>
	static void WarpAffine(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix, TransformFlag flags)
	{
		cvWarpAffine(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer(), (int)flags);
	}

	/// <summary>
	/// Warps image with affine transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void WarpAffine(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix)
	{
		cvWarpAffine(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer());
	}

	/// <summary>
	/// Computes affine transform matrix for mapping src[i] to dst[i] (i=0,1,2)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static ManagedMat^ GetAffineTransform(array<NAMESPACE::Point2D32f>^ src, array<NAMESPACE::Point2D32f>^ dst, ManagedMat^ map_matrix)
	{
		pin_ptr<NAMESPACE::Point2D32f> psrc = &src[0];
		pin_ptr<NAMESPACE::Point2D32f> pdst = &dst[0];
		return gcnew ManagedMat(cvGetAffineTransform((CvPoint2D32f*)psrc, (CvPoint2D32f*)pdst, map_matrix->ToCvMatPointer()), false);
	}

	/// <summary>
	/// Computes rotation_matrix matrix
	/// </summary>
	/// <param name="center"></param>
	/// <param name="angle"></param>
	/// <param name="scale"></param>
	/// <returns></returns>
	static ManagedMat^ RotationMatrix2D(NAMESPACE::Point2D32f center, double angle, double scale, ManagedMat^ map_matrix)
	{
		return gcnew ManagedMat(cv2DRotationMatrix(*(CvPoint2D32f*)&center, angle, scale, map_matrix->ToCvMatPointer()), false);
	}

	/// <summary>
	/// Warps image with perspective (projective) transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="map_matrix"></param>
	/// <param name="flags"></param>
	static void WarpPerspective(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix, TransformFlag flags, NAMESPACE::Scalar fillval)
	{
		cvWarpPerspective(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer(), (int)flags, *(CvScalar*)&fillval);
	}

	/// <summary>
	/// Warps image with perspective (projective) transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="map_matrix"></param>
	static void WarpPerspective(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix, TransformFlag flags)
	{
		cvWarpPerspective(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer(), (int)flags);
	}

	/// <summary>
	/// Warps image with perspective (projective) transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void WarpPerspective(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix)
	{
		cvWarpPerspective(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer());
	}

	/// <summary>
	/// Computes perspective transform matrix for mapping src[i] to dst[i] (i=0,1,2,3)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static ManagedMat^ GetPerspectiveTransform(array<NAMESPACE::Point2D32f>^ src, array<NAMESPACE::Point2D32f>^ dst, ManagedMat^ map_matrix)
	{
		pin_ptr<NAMESPACE::Point2D32f> psrc = &src[0];
		pin_ptr<NAMESPACE::Point2D32f> pdst = &dst[0];
		return gcnew ManagedMat(cvGetPerspectiveTransform((CvPoint2D32f*)psrc, (CvPoint2D32f*)pdst, map_matrix->ToCvMatPointer()), false);
	}

	/// <summary>
	/// Performs generic geometric transformation using the specified coordinate maps
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="mapx"></param>
	/// <param name="mapy"></param>
	/// <param name="flags"></param>
	static void Remap(ManagedArr^ src, ManagedArr^ dst, ManagedArr^ mapx, ManagedArr^ mapy, TransformFlag flags, NAMESPACE::Scalar fillval)
	{
		cvRemap(src->ToCvArrPointer(), dst->ToCvArrPointer(), mapx->ToCvArrPointer(), mapy->ToCvArrPointer(), (int)flags, *(CvScalar*)&fillval);
	}

	/// <summary>
	/// Performs generic geometric transformation using the specified coordinate maps
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="mapx"></param>
	/// <param name="mapy"></param>
	static void Remap(ManagedArr^ src, ManagedArr^ dst, ManagedArr^ mapx, ManagedArr^ mapy, TransformFlag flags)
	{
		cvRemap(src->ToCvArrPointer(), dst->ToCvArrPointer(), mapx->ToCvArrPointer(), mapy->ToCvArrPointer(), (int)flags);
	}

	/// <summary>
	/// Performs generic geometric transformation using the specified coordinate maps
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="mapx"></param>
	static void Remap(ManagedArr^ src, ManagedArr^ dst, ManagedArr^ mapx, ManagedArr^ mapy)
	{
		cvRemap(src->ToCvArrPointer(), dst->ToCvArrPointer(), mapx->ToCvArrPointer(), mapy->ToCvArrPointer());
	}

	/// <summary>
	/// Converts mapx & mapy from floating-point to integer formats for cvRemap
	/// </summary>
	/// <param name="mapx"></param>
	/// <param name="mapy"></param>
	/// <param name="mapxy"></param>
	static void ConvertMaps(ManagedArr^ mapx, ManagedArr^ mapy, ManagedArr^ mapxy, ManagedArr^ mapalpha)
	{
		cvConvertMaps(mapx->ToCvArrPointer(), mapy->ToCvArrPointer(), mapxy->ToCvArrPointer(), mapalpha->ToCvArrPointer());
	}

	/// <summary>
	/// Performs forward or inverse log-polar image transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="center"></param>
	/// <param name="M"></param>
	static void LogPolar(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32f center, double M, TransformFlag flags)
	{
		cvLogPolar(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint2D32f*)&center, M, (int)flags);
	}

	/// <summary>
	/// Performs forward or inverse log-polar image transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="center"></param>
	static void LogPolar(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32f center, double M)
	{
		cvLogPolar(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint2D32f*)&center, M);
	}

	/// <summary>
	/// Performs forward or inverse linear-polar image transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="center"></param>
	/// <param name="maxRadius"></param>
	static void LinearPolar(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32f center, double maxRadius, TransformFlag flags)
	{
		cvLinearPolar(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint2D32f*)&center, maxRadius, (int)flags);
	}

	/// <summary>
	/// Performs forward or inverse linear-polar image transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="center"></param>
	static void LinearPolar(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32f center, double maxRadius)
	{
		cvLinearPolar(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint2D32f*)&center, maxRadius);
	}

	/// <summary>
	/// creates structuring element used for morphological operations
	/// </summary>
	/// <param name="cols"></param>
	/// <param name="rows"></param>
	/// <param name="anchor_x"></param>
	/// <param name="anchor_y"></param>
	/// <param name="shape"></param>
	/// <returns></returns>
	static ManagedConvKernel^ CreateStructuringElementEx(int cols, int rows, int anchor_x, int anchor_y, ShapeType shape, array<int>^ values)
	{
		pin_ptr<int> pvalues = &values[0];
		return gcnew ManagedConvKernel(cvCreateStructuringElementEx(cols, rows, anchor_x, anchor_y, (int)shape, pvalues), true);
	}

	/// <summary>
	/// creates structuring element used for morphological operations
	/// </summary>
	/// <param name="cols"></param>
	/// <param name="rows"></param>
	/// <param name="anchor_x"></param>
	/// <param name="anchor_y"></param>
	/// <returns></returns>
	static ManagedConvKernel^ CreateStructuringElementEx(int cols, int rows, int anchor_x, int anchor_y, ShapeType shape)
	{
		return gcnew ManagedConvKernel(cvCreateStructuringElementEx(cols, rows, anchor_x, anchor_y, (int)shape), true);
	}

	/// <summary>
	/// releases structuring element
	/// </summary>
	static void ReleaseStructuringElement(ManagedConvKernel^% element)
	{
		IplConvKernel* pkernel = element->ToIplConvKernelPointer();
		cvReleaseStructuringElement(&pkernel);
		element->m_pHandle = pkernel;
	}

	/// <summary>
	/// erodes input image (applies minimum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="element"></param>
	static void Erode(ManagedArr^ src, ManagedArr^ dst, ManagedConvKernel^ element, int iterations)
	{
		cvErode(src->ToCvArrPointer(), dst->ToCvArrPointer(), element->ToIplConvKernelPointer(), iterations);
	}

	/// <summary>
	/// erodes input image (applies minimum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Erode(ManagedArr^ src, ManagedArr^ dst, ManagedConvKernel^ element)
	{
		cvErode(src->ToCvArrPointer(), dst->ToCvArrPointer(), element->ToIplConvKernelPointer());
	}

	/// <summary>
	/// erodes input image (applies minimum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	static void Erode(ManagedArr^ src, ManagedArr^ dst)
	{
		cvErode(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// dilates input image (applies maximum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="element"></param>
	static void Dilate(ManagedArr^ src, ManagedArr^ dst, ManagedConvKernel^ element, int iterations)
	{
		cvDilate(src->ToCvArrPointer(), dst->ToCvArrPointer(), element->ToIplConvKernelPointer(), iterations);
	}

	/// <summary>
	/// dilates input image (applies maximum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Dilate(ManagedArr^ src, ManagedArr^ dst, ManagedConvKernel^ element)
	{
		cvDilate(src->ToCvArrPointer(), dst->ToCvArrPointer(), element->ToIplConvKernelPointer());
	}

	/// <summary>
	/// dilates input image (applies maximum filter) one or more times.
	/// If element pointer is NULL, 3x3 rectangular element is used
	/// </summary>
	/// <param name="src"></param>
	static void Dilate(ManagedArr^ src, ManagedArr^ dst)
	{
		cvDilate(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Performs complex morphological transformation
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="temp"></param>
	/// <param name="element"></param>
	/// <param name="operation"></param>
	static void MorphologyEx(ManagedArr^ src, ManagedArr^ dst, ManagedArr^ temp, ManagedConvKernel^ element, MorphologyMethod operation, int iterations)
	{
		cvMorphologyEx(src->ToCvArrPointer(), dst->ToCvArrPointer(), temp->ToCvArrPointer(), element->ToIplConvKernelPointer(), (int)operation, iterations);
	}

	/// <summary>
	/// Performs complex morphological transformation
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="temp"></param>
	/// <param name="element"></param>
	static void MorphologyEx(ManagedArr^ src, ManagedArr^ dst, ManagedArr^ temp, ManagedConvKernel^ element, MorphologyMethod operation)
	{
		cvMorphologyEx(src->ToCvArrPointer(), dst->ToCvArrPointer(), temp->ToCvArrPointer(), element->ToIplConvKernelPointer(), (int)operation);
	}

	/// <summary>
	/// Calculates all spatial and central moments up to the 3rd order
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="moments"></param>
	static void Moments(ManagedArr^ arr, [OutAttribute] NAMESPACE::Moments% moments, bool binary)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		cvMoments(arr->ToCvArrPointer(), (CvMoments*)pmoments, (int)binary);
	}

	/// <summary>
	/// Calculates all spatial and central moments up to the 3rd order
	/// </summary>
	/// <param name="arr"></param>
	static void Moments(ManagedArr^ arr, [OutAttribute] NAMESPACE::Moments% moments)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		cvMoments(arr->ToCvArrPointer(), (CvMoments*)pmoments);
	}

	/// <summary>
	/// Retrieve particular spatial, central or normalized central moments
	/// </summary>
	/// <param name="moments"></param>
	/// <param name="x_order"></param>
	/// <returns></returns>
	static double GetSpatialMoment(NAMESPACE::Moments% moments, int x_order, int y_order)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		return cvGetSpatialMoment((CvMoments*)pmoments, x_order, y_order);
	}

	/// <summary>
	/// </summary>
	/// <param name="moments"></param>
	/// <param name="x_order"></param>
	/// <returns></returns>
	static double GetCentralMoment(NAMESPACE::Moments% moments, int x_order, int y_order)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		return cvGetCentralMoment((CvMoments*)pmoments, x_order, y_order);
	}

	/// <summary>
	/// </summary>
	/// <param name="moments"></param>
	/// <param name="x_order"></param>
	/// <returns></returns>
	static double GetNormalizedCentralMoment(NAMESPACE::Moments% moments, int x_order, int y_order)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		return cvGetNormalizedCentralMoment((CvMoments*)pmoments, x_order, y_order);
	}

	/// <summary>
	/// Calculates 7 Hu's invariants from precalculated spatial and central moments
	/// </summary>
	/// <param name="moments"></param>
	static void GetHuMoments(NAMESPACE::Moments% moments, [OutAttribute] NAMESPACE::HuMoments% hu_moments)
	{
		pin_ptr<NAMESPACE::Moments> pmoments = &moments;
		pin_ptr<NAMESPACE::HuMoments> phu_moments = &hu_moments;
		cvGetHuMoments((CvMoments*)pmoments, (CvHuMoments*)phu_moments);
	}

	/// <summary>
	/// Fetches pixels that belong to the specified line segment and stores them to the buffer.
	/// Returns the number of retrieved points.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="buffer"></param>
	/// <returns></returns>
	static int SampleLine(ManagedArr^ image, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, IntPtr buffer, PixelConnectType connectivity)
	{
		return cvSampleLine(image->ToCvArrPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, (void*)buffer.ToPointer(), (int)connectivity);
	}

	/// <summary>
	/// Fetches pixels that belong to the specified line segment and stores them to the buffer.
	/// Returns the number of retrieved points.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <returns></returns>
	static int SampleLine(ManagedArr^ image, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, IntPtr buffer)
	{
		return cvSampleLine(image->ToCvArrPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, (void*)buffer.ToPointer());
	}

	/// <summary>
	/// Retrieves the rectangular image region with specified center from the input array.
	/// dst(x,y) <- src(x + center.x - dst_width/2, y + center.y - dst_height/2).
	/// Values of pixels with fractional coordinates are retrieved using bilinear interpolation
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void GetRectSubPix(ManagedArr^ src, ManagedArr^ dst, NAMESPACE::Point2D32f center)
	{
		cvGetRectSubPix(src->ToCvArrPointer(), dst->ToCvArrPointer(), *(CvPoint2D32f*)&center);
	}

	/// <summary>
	/// Retrieves quadrangle from the input array.
	/// matrixarr = ( a11  a12 | b1 )   dst(x,y) <- src(A[x y]' + b)
	/// ( a21  a22 | b2 )   (bilinear interpolation is used to retrieve pixels
	/// with fractional coordinates)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void GetQuadrangleSubPix(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ map_matrix)
	{
		cvGetQuadrangleSubPix(src->ToCvArrPointer(), dst->ToCvArrPointer(), map_matrix->ToCvMatPointer());
	}

	/// <summary>
	/// Measures similarity between template and overlapped windows in the source image
	/// and fills the resultant image with the measurements
	/// </summary>
	/// <param name="image"></param>
	/// <param name="templ"></param>
	/// <param name="result"></param>
	static void MatchTemplate(ManagedArr^ image, ManagedArr^ templ, ManagedArr^ result, TemplateMatchMethod method)
	{
		cvMatchTemplate(image->ToCvArrPointer(), templ->ToCvArrPointer(), result->ToCvArrPointer(), (int)method);
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <param name="distance_type"></param>
	/// <param name="distance_func"></param>
	/// <param name="cost_matrix"></param>
	/// <param name="flow"></param>
	/// <param name="lower_bound"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type, DistanceFunction^ distance_func, ManagedArr^ cost_matrix, ManagedArr^ flow, IntPtr lower_bound, IntPtr userdata)
	{
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type,
			(CvDistanceFunction)Marshal::GetFunctionPointerForDelegate(distance_func).ToPointer(), 
			cost_matrix->ToCvArrPointer(), flow->ToCvArrPointer(), (float*)lower_bound.ToPointer(), (void*)userdata.ToPointer());
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <param name="distance_type"></param>
	/// <param name="distance_func"></param>
	/// <param name="cost_matrix"></param>
	/// <param name="flow"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type, DistanceFunction^ distance_func, ManagedArr^ cost_matrix, ManagedArr^ flow, float% lower_bound)
	{
		pin_ptr<float> plower_bound = &lower_bound;
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type, 
			(CvDistanceFunction)Marshal::GetFunctionPointerForDelegate(distance_func).ToPointer(), 
			cost_matrix->ToCvArrPointer(), flow->ToCvArrPointer(), plower_bound);
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <param name="distance_type"></param>
	/// <param name="distance_func"></param>
	/// <param name="cost_matrix"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type, DistanceFunction^ distance_func, ManagedArr^ cost_matrix, ManagedArr^ flow)
	{
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type, 
			(CvDistanceFunction)Marshal::GetFunctionPointerForDelegate(distance_func).ToPointer(), 
			cost_matrix->ToCvArrPointer(), flow->ToCvArrPointer());
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <param name="distance_type"></param>
	/// <param name="distance_func"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type, DistanceFunction^ distance_func, ManagedArr^ cost_matrix)
	{
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type, 
			(CvDistanceFunction)Marshal::GetFunctionPointerForDelegate(distance_func).ToPointer(), 
			cost_matrix->ToCvArrPointer());
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <param name="distance_type"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type, DistanceFunction^ distance_func)
	{
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type, 
			(CvDistanceFunction)Marshal::GetFunctionPointerForDelegate(distance_func).ToPointer());
	}

	/// <summary>
	/// Computes earth mover distance between
	/// two weighted point sets (called signatures)
	/// </summary>
	/// <param name="signature1"></param>
	/// <param name="signature2"></param>
	/// <returns></returns>
	static float CalcEMD2(ManagedArr^ signature1, ManagedArr^ signature2, DistanceType distance_type)
	{
		return cvCalcEMD2(signature1->ToCvArrPointer(), signature2->ToCvArrPointer(), (int)distance_type);
	}

	/// <summary>
	/// Retrieves outer and optionally inner boundaries of white (non-zero) connected
	/// components in the black (zero) background
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="first_contour"></param>
	/// <param name="header_size"></param>
	/// <param name="mode"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static int FindContours(ManagedArr^ image, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% first_contour, int header_size, ContourRetrMode mode, ContourApproxMethod method, NAMESPACE::Point2D32s offset)
	{
		CvSeq* pfirst_contour = NULL;
		int nRet = cvFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), &pfirst_contour, header_size, (int)mode, (int)method, *(CvPoint*)&offset);
		first_contour = gcnew ManagedSeq(pfirst_contour);
		return nRet;
	}

	/// <summary>
	/// Retrieves outer and optionally inner boundaries of white (non-zero) connected
	/// components in the black (zero) background
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="first_contour"></param>
	/// <param name="header_size"></param>
	/// <param name="mode"></param>
	/// <returns></returns>
	static int FindContours(ManagedArr^ image, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% first_contour, int header_size, ContourRetrMode mode, ContourApproxMethod method)
	{
		CvSeq* pfirst_contour = NULL;
		int nRet = cvFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), &pfirst_contour, header_size, (int)mode, (int)method);
		first_contour = gcnew ManagedSeq(pfirst_contour);
		return nRet;
	}

	/// <summary>
	/// Retrieves outer and optionally inner boundaries of white (non-zero) connected
	/// components in the black (zero) background
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="first_contour"></param>
	/// <param name="header_size"></param>
	/// <returns></returns>
	static int FindContours(ManagedArr^ image, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% first_contour, int header_size, ContourRetrMode mode)
	{
		CvSeq* pfirst_contour = NULL;
		int nRet = cvFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), &pfirst_contour, header_size, (int)mode);
		first_contour = gcnew ManagedSeq(pfirst_contour);
		return nRet;
	}

	/// <summary>
	/// Retrieves outer and optionally inner boundaries of white (non-zero) connected
	/// components in the black (zero) background
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="first_contour"></param>
	/// <returns></returns>
	static int FindContours(ManagedArr^ image, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% first_contour, int header_size)
	{
		CvSeq* pfirst_contour = NULL;
		int nRet = cvFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), &pfirst_contour, header_size);
		first_contour = gcnew ManagedSeq(pfirst_contour);
		return nRet;
	}

	/// <summary>
	/// Retrieves outer and optionally inner boundaries of white (non-zero) connected
	/// components in the black (zero) background
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static int FindContours(ManagedArr^ image, ManagedMemStorage^ storage, [OutAttribute] ManagedSeq^% first_contour)
	{
		CvSeq* pfirst_contour = NULL;
		int nRet = cvFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), &pfirst_contour);
		first_contour = gcnew ManagedSeq(pfirst_contour);
		return nRet;
	}

	/// <summary>
	/// Initalizes contour retrieving process.
	/// Calls cvStartFindContours.
	/// Calls cvFindNextContour until null pointer is returned
	/// or some other condition becomes true.
	/// Calls cvEndFindContours at the end.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="header_size"></param>
	/// <param name="mode"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static ManagedContourScanner^ StartFindContours(ManagedArr^ image, ManagedMemStorage^ storage, int header_size, ContourRetrMode mode, ContourApproxMethod method, NAMESPACE::Point2D32s offset)
	{
		CvContourScanner scanner = cvStartFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), header_size, (int)mode, (int)method, *(CvPoint*)&offset);
		return gcnew ManagedContourScanner(scanner, true);
	}

	/// <summary>
	/// Initalizes contour retrieving process.
	/// Calls cvStartFindContours.
	/// Calls cvFindNextContour until null pointer is returned
	/// or some other condition becomes true.
	/// Calls cvEndFindContours at the end.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="header_size"></param>
	/// <param name="mode"></param>
	/// <returns></returns>
	static ManagedContourScanner^ StartFindContours(ManagedArr^ image, ManagedMemStorage^ storage, int header_size, ContourRetrMode mode, ContourApproxMethod method)
	{
		CvContourScanner scanner = cvStartFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), header_size, (int)mode, (int)method);
		return gcnew ManagedContourScanner(scanner, true);
	}

	/// <summary>
	/// Initalizes contour retrieving process.
	/// Calls cvStartFindContours.
	/// Calls cvFindNextContour until null pointer is returned
	/// or some other condition becomes true.
	/// Calls cvEndFindContours at the end.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <param name="header_size"></param>
	/// <returns></returns>
	static ManagedContourScanner^ StartFindContours(ManagedArr^ image, ManagedMemStorage^ storage, int header_size, ContourRetrMode mode)
	{
		CvContourScanner scanner = cvStartFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), header_size, (int)mode);
		return gcnew ManagedContourScanner(scanner, true);
	}

	/// <summary>
	/// Initalizes contour retrieving process.
	/// Calls cvStartFindContours.
	/// Calls cvFindNextContour until null pointer is returned
	/// or some other condition becomes true.
	/// Calls cvEndFindContours at the end.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedContourScanner^ StartFindContours(ManagedArr^ image, ManagedMemStorage^ storage, int header_size)
	{
		CvContourScanner scanner = cvStartFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer(), header_size);
		return gcnew ManagedContourScanner(scanner, true);
	}

	/// <summary>
	/// Initalizes contour retrieving process.
	/// Calls cvStartFindContours.
	/// Calls cvFindNextContour until null pointer is returned
	/// or some other condition becomes true.
	/// Calls cvEndFindContours at the end.
	/// </summary>
	/// <param name="image"></param>
	/// <returns></returns>
	static ManagedContourScanner^ StartFindContours(ManagedArr^ image, ManagedMemStorage^ storage)
	{
		CvContourScanner scanner = cvStartFindContours(image->ToCvArrPointer(), storage->ToCvMemStoragePointer());
		return gcnew ManagedContourScanner(scanner, true);
	}

	/// <summary>
	/// Retrieves next contour
	/// </summary>
	/// <returns></returns>
	static ManagedSeq^ FindNextContour(ManagedContourScanner^ scanner)
	{
		return gcnew ManagedSeq(cvFindNextContour(scanner->ToCvContourScanner()));
	}

	/// <summary>
	/// Substitutes the last retrieved contour with the new one
	/// (if the substitutor is null, the last retrieved contour is removed from the tree)
	/// </summary>
	/// <param name="scanner"></param>
	static void SubstituteContour(ManagedContourScanner^ scanner, IntPtr new_contour)
	{
		cvSubstituteContour(*(CvContourScanner*)&scanner, (CvSeq*)new_contour.ToPointer());
	}

	/// <summary>
	/// Releases contour scanner and returns pointer to the first outer contour
	/// </summary>
	/// <returns></returns>
	static ManagedSeq^ EndFindContours(ManagedContourScanner^% scanner)
	{
		CvContourScanner pscanner = scanner->ToCvContourScanner();
		ManagedSeq^ seq = gcnew ManagedSeq(cvEndFindContours(&pscanner));
		scanner->m_pHandle = pscanner;
		return seq;
	}
	/// <summary>
	/// Approximates a single Freeman chain or a tree of chains to polygonal curves
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter"></param>
	/// <param name="minimal_perimeter"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxChains(ManagedSeq^ src_seq, ManagedMemStorage^ storage, ContourApproxMethod method, double parameter, int minimal_perimeter, bool recursive)
	{
		return gcnew ManagedSeq(cvApproxChains(src_seq->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter, minimal_perimeter, (int)recursive));
	}

	/// <summary>
	/// Approximates a single Freeman chain or a tree of chains to polygonal curves
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxChains(ManagedSeq^ src_seq, ManagedMemStorage^ storage, ContourApproxMethod method, double parameter, int minimal_perimeter)
	{
		return gcnew ManagedSeq(cvApproxChains(src_seq->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter, minimal_perimeter));
	}

	/// <summary>
	/// Approximates a single Freeman chain or a tree of chains to polygonal curves
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxChains(ManagedSeq^ src_seq, ManagedMemStorage^ storage, ContourApproxMethod method, double parameter)
	{
		return gcnew ManagedSeq(cvApproxChains(src_seq->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter));
	}

	/// <summary>
	/// Approximates a single Freeman chain or a tree of chains to polygonal curves
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxChains(ManagedSeq^ src_seq, ManagedMemStorage^ storage, ContourApproxMethod method)
	{
		return gcnew ManagedSeq(cvApproxChains(src_seq->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method));
	}

	/// <summary>
	/// Approximates a single Freeman chain or a tree of chains to polygonal curves
	/// </summary>
	/// <param name="src_seq"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxChains(ManagedSeq^ src_seq, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSeq(cvApproxChains(src_seq->ToCvSeqPointer(), storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// Initalizes Freeman chain reader.
	/// The reader is used to iteratively get coordinates of all the chain points.
	/// If the Freeman codes should be read as is, a simple sequence reader should be used
	/// </summary>
	/// <param name="chain"></param>
	static void StartReadChainPoints(ManagedChain^ chain, ManagedChainPtReader^% reader)
	{
		cvStartReadChainPoints(chain->ToCvChainPointer(), reader->ToChainPtReaderPointer());
	}

	/// <summary>
	/// Retrieves the next chain point
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::Point2D32s ReadChainPoint(ManagedChainPtReader^ reader)
	{
		return *(NAMESPACE::Point2D32s*)&cvReadChainPoint(reader->ToChainPtReaderPointer());
	}

	/// <summary>
	/// Calculates optical flow for 2 images using classical Lucas & Kanade algorithm
	/// </summary>
	/// <param name="prev"></param>
	/// <param name="curr"></param>
	/// <param name="win_size"></param>
	/// <param name="velx"></param>
	static void CalcOpticalFlowLK(ManagedArr^ prev, ManagedArr^ curr, NAMESPACE::Size2D32s win_size, ManagedArr^ velx, ManagedArr^ vely)
	{
		cvCalcOpticalFlowLK(prev->ToCvArrPointer(), curr->ToCvArrPointer(), *(CvSize*)&win_size, velx->ToCvArrPointer(), vely->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates optical flow for 2 images using block matching algorithm
	/// </summary>
	/// <param name="prev"></param>
	/// <param name="curr"></param>
	/// <param name="block_size"></param>
	/// <param name="shift_size"></param>
	/// <param name="max_range"></param>
	/// <param name="use_previous"></param>
	/// <param name="velx"></param>
	static void CalcOpticalFlowBM(ManagedArr^ prev, ManagedArr^ curr, NAMESPACE::Size2D32s block_size, NAMESPACE::Size2D32s shift_size, NAMESPACE::Size2D32s max_range, bool use_previous, ManagedArr^ velx, ManagedArr^ vely)
	{
		cvCalcOpticalFlowBM(prev->ToCvArrPointer(), curr->ToCvArrPointer(), *(CvSize*)&block_size, *(CvSize*)&shift_size, *(CvSize*)&max_range, (int)use_previous, velx->ToCvArrPointer(), vely->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates Optical flow for 2 images using Horn & Schunck algorithm
	/// </summary>
	/// <param name="prev"></param>
	/// <param name="curr"></param>
	/// <param name="use_previous"></param>
	/// <param name="velx"></param>
	/// <param name="vely"></param>
	/// <param name="lambda"></param>
	static void CalcOpticalFlowHS(ManagedArr^ prev, ManagedArr^ curr, bool use_previous, ManagedArr^ velx, ManagedArr^ vely, double lambda, NAMESPACE::TermCriteria criteria)
	{
		cvCalcOpticalFlowHS(prev->ToCvArrPointer(), curr->ToCvArrPointer(), (int)use_previous, velx->ToCvArrPointer(), vely->ToCvArrPointer(), lambda, *(CvTermCriteria*)&criteria);
	}
	/// <summary>
	/// It is Lucas & Kanade method, modified to use pyramids.
	/// Also it does several iterations to get optical flow for
	/// every point at every pyramid level.
	/// Calculates optical flow between two images for certain set of points (i.e.
	/// it is a "sparse" optical flow, which is opposite to the previous 3 methods)
	/// </summary>
	/// <param name="prev"></param>
	/// <param name="curr"></param>
	/// <param name="prev_pyr"></param>
	/// <param name="curr_pyr"></param>
	/// <param name="prev_features"></param>
	/// <param name="curr_features"></param>
	/// <param name="count"></param>
	/// <param name="win_size"></param>
	/// <param name="level"></param>
	/// <param name="status"></param>
	/// <param name="track_error"></param>
	/// <param name="criteria"></param>
	static void CalcOpticalFlowPyrLK(ManagedArr^ prev, ManagedArr^ curr, ManagedArr^ prev_pyr, ManagedArr^ curr_pyr, array<NAMESPACE::Point2D32f>^ prev_features, array<NAMESPACE::Point2D32f>^ curr_features, int count, NAMESPACE::Size2D32s win_size, int level, [OutAttribute] array<char>^% status, [OutAttribute] array<float>^% track_error, NAMESPACE::TermCriteria criteria, LKFlowFlag flags)
	{
		pin_ptr<NAMESPACE::Point2D32f> pprev_features = &prev_features[0];
		pin_ptr<NAMESPACE::Point2D32f> pcurr_features = &curr_features[0];
		status = gcnew array<char>(count);
		track_error = gcnew array<float>(count);
		pin_ptr<char> pstatus = &status[0];
		pin_ptr<float> ptrack_error = &track_error[0];
		cvCalcOpticalFlowPyrLK(prev->ToCvArrPointer(), curr->ToCvArrPointer(), prev_pyr->ToCvArrPointer(), curr_pyr->ToCvArrPointer(), (CvPoint2D32f*)pprev_features, (CvPoint2D32f*)pcurr_features, count, *(CvSize*)&win_size, level, pstatus, ptrack_error, *(CvTermCriteria*)&criteria, (int)flags);
	}

	/// <summary>
	/// Modification of a previous sparse optical flow algorithm to calculate
	/// affine flow
	/// </summary>
	/// <param name="prev"></param>
	/// <param name="curr"></param>
	/// <param name="prev_pyr"></param>
	/// <param name="curr_pyr"></param>
	/// <param name="prev_features"></param>
	/// <param name="curr_features"></param>
	/// <param name="matrices"></param>
	/// <param name="count"></param>
	/// <param name="win_size"></param>
	/// <param name="level"></param>
	/// <param name="status"></param>
	/// <param name="track_error"></param>
	/// <param name="criteria"></param>
	static void CalcAffineFlowPyrLK(ManagedArr^ prev, ManagedArr^ curr, ManagedArr^ prev_pyr, ManagedArr^ curr_pyr, array<NAMESPACE::Point2D32f>^ prev_features, array<NAMESPACE::Point2D32f>^ curr_features, array<float>^% matrices, int count, NAMESPACE::Size2D32s win_size, int level, [OutAttribute] array<char>^% status, [OutAttribute] array<float>^% track_error, NAMESPACE::TermCriteria criteria, LKFlowFlag flags)
	{
		pin_ptr<NAMESPACE::Point2D32f> pprev_features = &prev_features[0];
		pin_ptr<NAMESPACE::Point2D32f> pcurr_features = &curr_features[0];
		status = gcnew array<char>(count);
		track_error = gcnew array<float>(count);
		pin_ptr<char> pstatus = &status[0];
		pin_ptr<float> ptrack_error = &track_error[0];
		pin_ptr<float> pmatrices = &matrices[0];
		cvCalcAffineFlowPyrLK(prev->ToCvArrPointer(), curr->ToCvArrPointer(), prev_pyr->ToCvArrPointer(), curr_pyr->ToCvArrPointer(), (CvPoint2D32f*)pprev_features, (CvPoint2D32f*)pcurr_features, pmatrices, count, *(CvSize*)&win_size, level, pstatus, ptrack_error, *(CvTermCriteria*)&criteria, (int)flags);
	}

	/// <summary>
	/// Estimate rigid transformation between 2 images or 2 point sets
	/// </summary>
	/// <param name="A"></param>
	/// <param name="B"></param>
	/// <param name="M"></param>
	/// <returns></returns>
	static int EstimateRigidTransform(ManagedArr^ A, ManagedArr^ B, ManagedMat^ M, bool full_affine)
	{
		return cvEstimateRigidTransform(A->ToCvArrPointer(), B->ToCvArrPointer(), M->ToCvMatPointer(), (int)full_affine);
	}

	/// <summary>
	/// Updates motion history image given motion silhouette
	/// </summary>
	/// <param name="silhouette"></param>
	/// <param name="mhi"></param>
	/// <param name="timestamp"></param>
	static void UpdateMotionHistory(ManagedArr^ silhouette, ManagedArr^ mhi, double timestamp, double duration)
	{
		cvUpdateMotionHistory(silhouette->ToCvArrPointer(), mhi->ToCvArrPointer(), timestamp, duration);
	}

	/// <summary>
	/// Calculates gradient of the motion history image and fills
	/// a mask indicating where the gradient is valid
	/// </summary>
	/// <param name="mhi"></param>
	/// <param name="mask"></param>
	/// <param name="orientation"></param>
	/// <param name="delta1"></param>
	/// <param name="delta2"></param>
	static void CalcMotionGradient(ManagedArr^ mhi, ManagedArr^ mask, ManagedArr^ orientation, double delta1, double delta2, ApertureSize aperture_size)
	{
		cvCalcMotionGradient(mhi->ToCvArrPointer(), mask->ToCvArrPointer(), orientation->ToCvArrPointer(), delta1, delta2, (int)aperture_size);
	}

	/// <summary>
	/// Calculates gradient of the motion history image and fills
	/// a mask indicating where the gradient is valid
	/// </summary>
	/// <param name="mhi"></param>
	/// <param name="mask"></param>
	/// <param name="orientation"></param>
	/// <param name="delta1"></param>
	static void CalcMotionGradient(ManagedArr^ mhi, ManagedArr^ mask, ManagedArr^ orientation, double delta1, double delta2)
	{
		cvCalcMotionGradient(mhi->ToCvArrPointer(), mask->ToCvArrPointer(), orientation->ToCvArrPointer(), delta1, delta2);
	}

	/// <summary>
	/// Calculates average motion direction within a selected motion region
	/// (region can be selected by setting ROIs and/or by composing a valid gradient mask
	/// with the region mask)
	/// </summary>
	/// <param name="orientation"></param>
	/// <param name="mask"></param>
	/// <param name="mhi"></param>
	/// <param name="timestamp"></param>
	/// <returns></returns>
	static double CalcGlobalOrientation(ManagedArr^ orientation, ManagedArr^ mask, ManagedArr^ mhi, double timestamp, double duration)
	{
		return cvCalcGlobalOrientation(orientation->ToCvArrPointer(), mask->ToCvArrPointer(), mhi->ToCvArrPointer(), timestamp, duration);
	}

	/// <summary>
	/// Splits a motion history image into a few parts corresponding to separate independent motions
	/// (e.g. left hand, right hand)
	/// </summary>
	/// <param name="mhi"></param>
	/// <param name="seg_mask"></param>
	/// <param name="storage"></param>
	/// <param name="timestamp"></param>
	/// <returns></returns>
	static IntPtr SegmentMotion(ManagedArr^ mhi, ManagedArr^ seg_mask, ManagedMemStorage^ storage, double timestamp, double seg_thresh)
	{
		return IntPtr(cvSegmentMotion(mhi->ToCvArrPointer(), seg_mask->ToCvArrPointer(), storage->ToCvMemStoragePointer(), timestamp, seg_thresh));
	}

	/// <summary>
	/// Adds image to accumulator
	/// </summary>
	/// <param name="image"></param>
	/// <param name="sum"></param>
	static void Acc(ManagedArr^ image, ManagedArr^ sum, ManagedArr^ mask)
	{
		cvAcc(image->ToCvArrPointer(), sum->ToCvArrPointer(), mask->ToCvArrPointer());
	}

	/// <summary>
	/// Adds image to accumulator
	/// </summary>
	/// <param name="image"></param>
	static void Acc(ManagedArr^ image, ManagedArr^ sum)
	{
		cvAcc(image->ToCvArrPointer(), sum->ToCvArrPointer());
	}

	/// <summary>
	/// Adds squared image to accumulator
	/// </summary>
	/// <param name="image"></param>
	/// <param name="sqsum"></param>
	static void SquareAcc(ManagedArr^ image, ManagedArr^ sqsum, ManagedArr^ mask)
	{
		cvSquareAcc(image->ToCvArrPointer(), sqsum->ToCvArrPointer(), mask->ToCvArrPointer());
	}

	/// <summary>
	/// Adds squared image to accumulator
	/// </summary>
	/// <param name="image"></param>
	static void SquareAcc(ManagedArr^ image, ManagedArr^ sqsum)
	{
		cvSquareAcc(image->ToCvArrPointer(), sqsum->ToCvArrPointer());
	}

	/// <summary>
	/// Adds a product of two images to accumulator
	/// </summary>
	/// <param name="image1"></param>
	/// <param name="image2"></param>
	/// <param name="acc"></param>
	static void MultiplyAcc(ManagedArr^ image1, ManagedArr^ image2, ManagedArr^ acc, ManagedArr^ mask)
	{
		cvMultiplyAcc(image1->ToCvArrPointer(), image2->ToCvArrPointer(), acc->ToCvArrPointer(), mask->ToCvArrPointer());
	}

	/// <summary>
	/// Adds a product of two images to accumulator
	/// </summary>
	/// <param name="image1"></param>
	/// <param name="image2"></param>
	static void MultiplyAcc(ManagedArr^ image1, ManagedArr^ image2, ManagedArr^ acc)
	{
		cvMultiplyAcc(image1->ToCvArrPointer(), image2->ToCvArrPointer(), acc->ToCvArrPointer());
	}

	/// <summary>
	/// Adds image to accumulator with weights: acc = acc*(1-alpha) + image*alpha
	/// </summary>
	/// <param name="image"></param>
	/// <param name="acc"></param>
	/// <param name="alpha"></param>
	static void RunningAvg(ManagedArr^ image, ManagedArr^ acc, double alpha, ManagedArr^ mask)
	{
		cvRunningAvg(image->ToCvArrPointer(), acc->ToCvArrPointer(), alpha, mask->ToCvArrPointer());
	}

	/// <summary>
	/// Adds image to accumulator with weights: acc = acc*(1-alpha) + image*alpha
	/// </summary>
	/// <param name="image"></param>
	/// <param name="acc"></param>
	static void RunningAvg(ManagedArr^ image, ManagedArr^ acc, double alpha)
	{
		cvRunningAvg(image->ToCvArrPointer(), acc->ToCvArrPointer(), alpha);
	}

	/// <summary>
	/// Implements CAMSHIFT algorithm - determines object position, size and orientation
	/// from the object histogram back project (extension of meanshift)
	/// </summary>
	/// <param name="prob_image"></param>
	/// <param name="window"></param>
	/// <param name="criteria"></param>
	/// <param name="comp"></param>
	/// <returns></returns>
	static int CamShift(ManagedArr^ prob_image, NAMESPACE::Rect window, NAMESPACE::TermCriteria criteria, [OutAttribute] ManagedConnectedComp^% comp, [OutAttribute] NAMESPACE::Box2D% box)
	{
		comp = gcnew ManagedConnectedComp();
		pin_ptr<NAMESPACE::Box2D> pbox = &box;
		return cvCamShift(prob_image->ToCvArrPointer(), *(CvRect*)&window, *(CvTermCriteria*)&criteria, comp->ToConnectedCompPointer(), (CvBox2D*)pbox);
	}

	/// <summary>
	/// Implements CAMSHIFT algorithm - determines object position, size and orientation
	/// from the object histogram back project (extension of meanshift)
	/// </summary>
	/// <param name="prob_image"></param>
	/// <param name="window"></param>
	/// <param name="criteria"></param>
	/// <returns></returns>
	static int CamShift(ManagedArr^ prob_image, NAMESPACE::Rect window, NAMESPACE::TermCriteria criteria, [OutAttribute] ManagedConnectedComp^% comp)
	{
		comp = gcnew ManagedConnectedComp();
		return cvCamShift(prob_image->ToCvArrPointer(), *(CvRect*)&window, *(CvTermCriteria*)&criteria, comp->ToConnectedCompPointer());
	}

	/// <summary>
	/// Implements MeanShift algorithm - determines object position
	/// from the object histogram back project
	/// </summary>
	/// <param name="prob_image"></param>
	/// <param name="window"></param>
	/// <param name="criteria"></param>
	/// <returns></returns>
	static int MeanShift(ManagedArr^ prob_image, NAMESPACE::Rect window, NAMESPACE::TermCriteria criteria, [OutAttribute] ManagedConnectedComp^% comp)
	{
		comp = gcnew ManagedConnectedComp();
		return cvMeanShift(prob_image->ToCvArrPointer(), *(CvRect*)&window, *(CvTermCriteria*)&criteria, comp->ToConnectedCompPointer());
	}

	/// <summary>
	/// Creates ConDensation filter state
	/// </summary>
	/// <param name="dynam_params"></param>
	/// <param name="measure_params"></param>
	/// <returns></returns>
	static ManagedConDensation^ CreateConDensation(int dynam_params, int measure_params, int sample_count)
	{
		return gcnew ManagedConDensation(cvCreateConDensation(dynam_params, measure_params, sample_count), true);
	}

	/// <summary>
	/// Releases ConDensation filter state
	/// </summary>
	static void ReleaseConDensation(ManagedConDensation^% condens)
	{
		CvConDensation* pConDensation = condens->ToConDensationPointer();
		cvReleaseConDensation(&pConDensation);
		condens->m_pHandle = pConDensation;
	}

	/// <summary>
	/// Updates ConDensation filter by time (predict future state of the system)
	/// </summary>
	static void ConDensUpdateByTime(ManagedConDensation^ condens)
	{
		cvConDensUpdateByTime(condens->ToConDensationPointer());
	}

	/// <summary>
	/// Initializes ConDensation filter samples
	/// </summary>
	/// <param name="condens"></param>
	/// <param name="lower_bound"></param>
	static void ConDensInitSampleSet(ManagedConDensation^ condens, ManagedMat^ lower_bound, ManagedMat^ upper_bound)
	{
		cvConDensInitSampleSet(condens->ToConDensationPointer(), lower_bound->ToCvMatPointer(), upper_bound->ToCvMatPointer());
	}

	/// <summary>
	/// Creates Kalman filter and sets A, B, Q, R and state to some initial values
	/// </summary>
	/// <param name="dynam_params"></param>
	/// <param name="measure_params"></param>
	/// <returns></returns>
	static ManagedKalman^ CreateKalman(int dynam_params, int measure_params, int control_params)
	{
		return gcnew ManagedKalman(cvCreateKalman(dynam_params, measure_params, control_params), true);
	}

	/// <summary>
	/// Creates Kalman filter and sets A, B, Q, R and state to some initial values
	/// </summary>
	/// <param name="dynam_params"></param>
	/// <returns></returns>
	static ManagedKalman^ CreateKalman(int dynam_params, int measure_params)
	{
		return gcnew ManagedKalman(cvCreateKalman(dynam_params, measure_params), true);
	}

	/// <summary>
	/// Releases Kalman filter state
	/// </summary>
	static void ReleaseKalman(ManagedKalman^% kalman)
	{
		CvKalman* pKalman = kalman->ToKalmanPointer();
		cvReleaseKalman(&pKalman);
		kalman->m_pHandle = pKalman;
	}

	/// <summary>
	/// Updates Kalman filter by time (predicts future state of the system)
	/// </summary>
	/// <param name="kalman"></param>
	/// <returns></returns>
	static ManagedMat^ KalmanPredict(ManagedKalman^ kalman, ManagedMat^ control)
	{
		return gcnew ManagedMat((CvMat*)cvKalmanPredict(kalman->ToKalmanPointer(), control->ToCvMatPointer()), false);
	}

	/// <summary>
	/// Updates Kalman filter by time (predicts future state of the system)
	/// </summary>
	/// <returns></returns>
	static ManagedMat^ KalmanPredict(ManagedKalman^ kalman)
	{
		return gcnew ManagedMat((CvMat*)cvKalmanPredict(kalman->ToKalmanPointer()), false);
	}

	/// <summary>
	/// Updates Kalman filter by measurement
	/// (corrects state of the system and internal matrices)
	/// </summary>
	/// <param name="kalman"></param>
	/// <returns></returns>
	static ManagedMat^ KalmanCorrect(ManagedKalman^ kalman, ManagedMat^ measurement)
	{
		return gcnew ManagedMat((CvMat*)cvKalmanCorrect(kalman->ToKalmanPointer(), measurement->ToCvMatPointer()), false);
	}

	/// <summary>
	/// Initializes Delaunay triangulation
	/// </summary>
	/// <param name="subdiv"></param>
	static void InitSubdivDelaunay2D(ManagedSubdiv2D^ subdiv, NAMESPACE::Rect rect)
	{
		cvInitSubdivDelaunay2D(subdiv->ToCvSubdiv2DPointer(), *(CvRect*)&rect);
	}

	/// <summary>
	/// Creates new subdivision
	/// </summary>
	/// <param name="subdiv_type"></param>
	/// <param name="header_size"></param>
	/// <param name="vtx_size"></param>
	/// <param name="quadedge_size"></param>
	/// <returns></returns>
	static ManagedSubdiv2D^ CreateSubdiv2D(int subdiv_type, int header_size, int vtx_size, int quadedge_size, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSubdiv2D(cvCreateSubdiv2D(subdiv_type, header_size, vtx_size, quadedge_size, storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// Inserts new point to the Delaunay triangulation
	/// </summary>
	/// <param name="subdiv"></param>
	/// <returns></returns>
	static IntPtr SubdivDelaunay2DInsert(ManagedSubdiv2D^ subdiv, NAMESPACE::Point2D32f pt)
	{
		return IntPtr(cvSubdivDelaunay2DInsert(subdiv->ToCvSubdiv2DPointer(), *(CvPoint2D32f*)&pt));
	}

	/// <summary>
	/// Locates a point within the Delaunay triangulation (finds the edge
	/// the point is left to or belongs to, or the triangulation point the given
	/// point coinsides with
	/// </summary>
	/// <param name="subdiv"></param>
	/// <param name="pt"></param>
	/// <param name="edge"></param>
	/// <returns></returns>
	static NAMESPACE::Subdiv2DPointLocation Subdiv2DLocate(ManagedSubdiv2D^ subdiv, NAMESPACE::Point2D32f pt, [OutAttribute] NAMESPACE::Subdiv2DEdge% edge, [OutAttribute] IntPtr% vertex)
	{
		pin_ptr<size_t> pedge = &edge.Value;
		CvSubdiv2DPoint* pvertex = NULL;
		CvSubdiv2DPointLocation location = cvSubdiv2DLocate(subdiv->ToCvSubdiv2DPointer(), *(CvPoint2D32f*)&pt, (CvSubdiv2DEdge*)pedge, &pvertex);
		vertex = IntPtr(pvertex);
		return (NAMESPACE::Subdiv2DPointLocation)location;
	}

	/// <summary>
	/// Locates a point within the Delaunay triangulation (finds the edge
	/// the point is left to or belongs to, or the triangulation point the given
	/// point coinsides with
	/// </summary>
	/// <param name="subdiv"></param>
	/// <param name="pt"></param>
	/// <returns></returns>
	static NAMESPACE::Subdiv2DPointLocation Subdiv2DLocate(ManagedSubdiv2D^ subdiv, NAMESPACE::Point2D32f pt, [OutAttribute] NAMESPACE::Subdiv2DEdge% edge)
	{
		pin_ptr<size_t> pedge = &edge.Value;
		CvSubdiv2DPointLocation location = cvSubdiv2DLocate(subdiv->ToCvSubdiv2DPointer(), *(CvPoint2D32f*)&pt, (CvSubdiv2DEdge*)pedge);
		return (NAMESPACE::Subdiv2DPointLocation)location;
	}

	/// <summary>
	/// Calculates Voronoi tesselation (i.e. coordinates of Voronoi points)
	/// </summary>
	static void CalcSubdivVoronoi2D(ManagedSubdiv2D^ subdiv)
	{
		cvCalcSubdivVoronoi2D(subdiv->ToCvSubdiv2DPointer());
	}

	/// <summary>
	/// Removes all Voronoi points from the tesselation
	/// </summary>
	static void ClearSubdivVoronoi2D(ManagedSubdiv2D^ subdiv)
	{
		cvClearSubdivVoronoi2D(subdiv->ToCvSubdiv2DPointer());
	}

	/// <summary>
	/// Finds the nearest to the given point vertex in subdivision.
	/// </summary>
	/// <param name="subdiv"></param>
	/// <returns></returns>
	static IntPtr FindNearestPoint2D(ManagedSubdiv2D^ subdiv, NAMESPACE::Point2D32f pt)
	{
		return IntPtr(cvFindNearestPoint2D(subdiv->ToCvSubdiv2DPointer(), *(CvPoint2D32f*)&pt));
	}

	/// <summary>
	/// Approximates a single polygonal curve (contour) or
	/// a tree of polygonal curves (contours)
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="header_size"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxPoly(ManagedArr^ src_seq, int header_size, ManagedMemStorage^ storage, PolyAproxMethod method, double parameter, int parameter2)
	{
		return gcnew ManagedSeq(cvApproxPoly(src_seq->ToCvArrPointer(), header_size, storage->ToCvMemStoragePointer(), (int)method, parameter, parameter2));
	}

	/// <summary>
	/// Approximates a single polygonal curve (contour) or
	/// a tree of polygonal curves (contours)
	/// </summary>
	/// <param name="src_seq"></param>
	/// <param name="header_size"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static ManagedSeq^ ApproxPoly(ManagedArr^ src_seq, int header_size, ManagedMemStorage^ storage, PolyAproxMethod method, double parameter)
	{
		return gcnew ManagedSeq(cvApproxPoly(src_seq->ToCvArrPointer(), header_size, storage->ToCvMemStoragePointer(), (int)method, parameter));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter1"></param>
	/// <param name="parameter2"></param>
	/// <param name="parameter3"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage, FindDominantMethod method, double parameter1, double parameter2, double parameter3, double parameter4)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter1, parameter2, parameter3, parameter4));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter1"></param>
	/// <param name="parameter2"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage, FindDominantMethod method, double parameter1, double parameter2, double parameter3)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter1, parameter2, parameter3));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <param name="parameter1"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage, FindDominantMethod method, double parameter1, double parameter2)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter1, parameter2));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage, FindDominantMethod method, double parameter1)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method, parameter1));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage, FindDominantMethod method)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), (int)method));
	}

	/// <summary>
	/// Finds high-curvature points of the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <returns></returns>
	static ManagedSeq^ FindDominantPoints(ManagedSeq^ contour, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSeq(cvFindDominantPoints(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// Calculates perimeter of a contour or length of a part of contour
	/// </summary>
	/// <param name="curve"></param>
	/// <param name="slice"></param>
	/// <returns></returns>
	static double ArcLength(ManagedArr^ curve, NAMESPACE::Slice slice, bool is_closed)
	{
		return cvArcLength(curve->ToCvArrPointer(), *(CvSlice*)&slice, (int)is_closed);
	}

	/// <summary>
	/// Calculates perimeter of a contour or length of a part of contour
	/// </summary>
	/// <param name="curve"></param>
	/// <returns></returns>
	static double ArcLength(ManagedArr^ curve, NAMESPACE::Slice slice)
	{
		return cvArcLength(curve->ToCvArrPointer(), *(CvSlice*)&slice);
	}

	/// <summary>
	/// Calculates perimeter of a contour or length of a part of contour
	/// </summary>
	/// <returns></returns>
	static double ArcLength(ManagedArr^ curve)
	{
		return cvArcLength(curve->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates perimeter of a contour or length of a part of contour
	/// </summary>
	/// <param name="curve"></param>
	/// <param name="slice"></param>
	/// <returns></returns>
	static double ContourPerimeter(ManagedArr^ curve)
	{
		return cvContourPerimeter(curve->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates contour boundning rectangle (update=1) or
	/// just retrieves pre-calculated rectangle (update=0)
	/// </summary>
	/// <param name="points"></param>
	/// <returns></returns>
	static NAMESPACE::Rect BoundingRect(ManagedArr^ points, bool update)
	{
		return *(NAMESPACE::Rect*)&cvBoundingRect(points->ToCvArrPointer(), (int)update);
	}

	/// <summary>
	/// Calculates contour boundning rectangle (update=1) or
	/// just retrieves pre-calculated rectangle (update=0)
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::Rect BoundingRect(ManagedArr^ points)
	{
		return *(NAMESPACE::Rect*)&cvBoundingRect(points->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates area of a contour or contour segment
	/// </summary>
	/// <param name="contour"></param>
	/// <returns></returns>
	static double ContourArea(ManagedArr^ contour, NAMESPACE::Slice slice)
	{
		return cvContourArea(contour->ToCvArrPointer(), *(CvSlice*)&slice);
	}

	/// <summary>
	/// Calculates area of a contour or contour segment
	/// </summary>
	/// <returns></returns>
	static double ContourArea(ManagedArr^ contour)
	{
		return cvContourArea(contour->ToCvArrPointer());
	}

	/// <summary>
	/// Finds minimum area rotated rectangle bounding a set of points
	/// </summary>
	/// <param name="points"></param>
	/// <returns></returns>
	static NAMESPACE::Box2D MinAreaRect2(ManagedArr^ points, ManagedMemStorage^ storage)
	{
		return *(NAMESPACE::Box2D*)&cvMinAreaRect2(points->ToCvArrPointer(), storage->ToCvMemStoragePointer());
	}

	/// <summary>
	/// Finds minimum area rotated rectangle bounding a set of points
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::Box2D MinAreaRect2(ManagedArr^ points)
	{
		return *(NAMESPACE::Box2D*)&cvMinAreaRect2(points->ToCvArrPointer());
	}

	/// <summary>
	/// Finds minimum enclosing circle for a set of points
	/// </summary>
	/// <param name="points"></param>
	/// <param name="center"></param>
	/// <returns></returns>
	static int MinEnclosingCircle(ManagedArr^ points, [OutAttribute] NAMESPACE::Point2D32f% center, [OutAttribute] float% radius)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcenter = &center;
		pin_ptr<float> pradius = &radius;
		return cvMinEnclosingCircle(points->ToCvArrPointer(), (CvPoint2D32f*)pcenter, pradius);
	}

	/// <summary>
	/// Compares two contours by matching their moments
	/// </summary>
	/// <param name="object1"></param>
	/// <param name="object2"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static double MatchShapes(ManagedArr^ object1, ManagedArr^ object2, ContourMatchMethod method, double parameter)
	{
		return cvMatchShapes(object1->ToCvArrPointer(), object2->ToCvArrPointer(), (int)method, parameter);
	}

	/// <summary>
	/// Compares two contours by matching their moments
	/// </summary>
	/// <param name="object1"></param>
	/// <param name="object2"></param>
	/// <returns></returns>
	static double MatchShapes(ManagedArr^ object1, ManagedArr^ object2, ContourMatchMethod method)
	{
		return cvMatchShapes(object1->ToCvArrPointer(), object2->ToCvArrPointer(), (int)method);
	}

	/// <summary>
	/// Builds hierarhical representation of a contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedContourTree^ CreateContourTree(ManagedSeq^ contour, ManagedMemStorage^ storage, double threshold)
	{
		return gcnew ManagedContourTree(cvCreateContourTree(contour->ToCvSeqPointer(), storage->ToCvMemStoragePointer(), threshold));
	}

	/// <summary>
	/// Reconstruct (completelly or partially) contour a from contour tree
	/// </summary>
	/// <param name="tree"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedSeq^ ContourFromContourTree(ManagedContourTree^ tree, ManagedMemStorage^ storage, NAMESPACE::TermCriteria criteria)
	{
		return gcnew ManagedSeq(cvContourFromContourTree(tree->ToContourTreePointer(), storage->ToCvMemStoragePointer(), *(CvTermCriteria*)&criteria));
	}

	/// <summary>
	/// </summary>
	/// <param name="tree1"></param>
	/// <param name="tree2"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static double MatchContourTrees(ManagedContourTree^ tree1, ManagedContourTree^ tree2, ContourTreeMatchMethod method, double threshold)
	{
		return cvMatchContourTrees(tree1->ToContourTreePointer(), tree2->ToContourTreePointer(), (int)method, threshold);
	}

	/// <summary>
	/// Calculates histogram of a contour
	/// </summary>
	/// <param name="contour"></param>
	static void CalcPGH(ManagedSeq^ contour, ManagedHistogram^ hist)
	{
		cvCalcPGH(contour->ToCvSeqPointer(), hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// Calculates exact convex hull of 2d point set
	/// </summary>
	/// <param name="input"></param>
	/// <param name="hull_storage"></param>
	/// <param name="orientation"></param>
	/// <returns></returns>
	static ManagedSeq^ ConvexHull2(ManagedArr^ input, NativeHandleObject^ hull_storage, OrientationType orientation, bool return_points)
	{
		return gcnew ManagedSeq(cvConvexHull2(input->ToCvArrPointer(), hull_storage->ToNativePointer(), (int)orientation, (int)return_points));
	}

	/// <summary>
	/// Calculates exact convex hull of 2d point set
	/// </summary>
	/// <param name="input"></param>
	/// <param name="hull_storage"></param>
	/// <returns></returns>
	static ManagedSeq^ ConvexHull2(ManagedArr^ input, NativeHandleObject^ hull_storage, OrientationType orientation)
	{
		return gcnew ManagedSeq(cvConvexHull2(input->ToCvArrPointer(), hull_storage->ToNativePointer(), (int)orientation));
	}

	/// <summary>
	/// Calculates exact convex hull of 2d point set
	/// </summary>
	/// <param name="input"></param>
	/// <returns></returns>
	static ManagedSeq^ ConvexHull2(ManagedArr^ input, NativeHandleObject^ hull_storage)
	{
		return gcnew ManagedSeq(cvConvexHull2(input->ToCvArrPointer(), hull_storage->ToNativePointer()));
	}

	/// <summary>
	/// Calculates exact convex hull of 2d point set
	/// </summary>
	/// <returns></returns>
	static ManagedSeq^ ConvexHull2(ManagedArr^ input)
	{
		return gcnew ManagedSeq(cvConvexHull2(input->ToCvArrPointer()));
	}

	/// <summary>
	/// Checks whether the contour is convex or not (returns 1 if convex, 0 if not)
	/// </summary>
	/// <returns></returns>
	static int CheckContourConvexity(ManagedArr^ contour)
	{
		return cvCheckContourConvexity(contour->ToCvArrPointer());
	}

	/// <summary>
	/// Finds convexity defects for the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="convexhull"></param>
	/// <returns></returns>
	static ManagedSeq^ ConvexityDefects(ManagedArr^ contour, ManagedArr^ convexhull, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSeq(cvConvexityDefects(contour->ToCvArrPointer(), convexhull->ToCvArrPointer(), storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// Finds convexity defects for the contour
	/// </summary>
	/// <param name="contour"></param>
	/// <returns></returns>
	static ManagedSeq^ ConvexityDefects(ManagedArr^ contour, ManagedArr^ convexhull)
	{
		return gcnew ManagedSeq(cvConvexityDefects(contour->ToCvArrPointer(), convexhull->ToCvArrPointer()));
	}

	/// <summary>
	/// Fits ellipse into a set of 2d points
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::Box2D FitEllipse2(ManagedArr^ points)
	{
		return *(NAMESPACE::Box2D*)&cvFitEllipse2(points->ToCvArrPointer());
	}

	/// <summary>
	/// Finds minimum rectangle containing two given rectangles
	/// </summary>
	/// <param name="rect1"></param>
	/// <returns></returns>
	static NAMESPACE::Rect MaxRect(NAMESPACE::Rect rect1, NAMESPACE::Rect rect2)
	{
		return *(NAMESPACE::Rect*)&cvMaxRect((CvRect*)&rect1, (CvRect*)&rect2);
	}

	/// <summary>
	/// Finds coordinates of the box vertices
	/// </summary>
	/// <param name="box"></param>
	static void BoxPoints(NAMESPACE::Box2D box, [OutAttribute] array<NAMESPACE::Point2D32f>^% pt)
	{
		pt = gcnew array<NAMESPACE::Point2D32f>(4);
		pin_ptr<NAMESPACE::Point2D32f> ppt = &pt[0];
		cvBoxPoints(*(CvBox2D*)&box, (CvPoint2D32f*)ppt);
	}

	/// <summary>
	/// Initializes sequence header for a matrix (column or row vector) of points -
	/// a wrapper for cvMakeSeqHeaderForArray (it does not initialize bounding rectangle!!!)
	/// </summary>
	/// <param name="seq_kind"></param>
	/// <param name="mat"></param>
	/// <param name="contour_header"></param>
	/// <returns></returns>
	static ManagedSeq^ PointSeqFromMat(SeqFlag seq_kind, ManagedArr^ mat, ManagedContour^ contour_header, ManagedSeqBlock^ block)
	{
		return gcnew ManagedSeq(cvPointSeqFromMat((int)seq_kind, mat->ToCvArrPointer(), contour_header->ToCvContourPointer(), block->ToCvSeqBlockPointer()));
	}

	/// <summary>
	/// Checks whether the point is inside polygon, outside, on an edge (at a vertex).
	/// Returns positive, negative or zero value, correspondingly.
	/// Optionally, measures a signed distance between
	/// the point and the nearest polygon edge (measure_dist=1)
	/// </summary>
	/// <param name="contour"></param>
	/// <param name="pt"></param>
	/// <returns></returns>
	static double PointPolygonTest(ManagedArr^ contour, NAMESPACE::Point2D32f pt, bool measure_dist)
	{
		return cvPointPolygonTest(contour->ToCvArrPointer(), *(CvPoint2D32f*)&pt, (int)measure_dist);
	}

	/// <summary>
	/// Creates new histogram
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <param name="ranges"></param>
	/// <returns></returns>
	static ManagedHistogram^ CreateHist(int dims, array<int>^ sizes, HistType type, array<float, 2>^ ranges, bool uniform)
	{
		pin_ptr<int> psizes = &sizes[0];
		pin_ptr<float> pranges = &ranges[0, 0];
		return gcnew ManagedHistogram(cvCreateHist(dims, psizes, (int)type, (float**)pranges, (int)uniform), true);
	}

	/// <summary>
	/// Creates new histogram
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static ManagedHistogram^ CreateHist(int dims, array<int>^ sizes, HistType type, array<float, 2>^ ranges)
	{
		pin_ptr<int> psizes = &sizes[0];
		pin_ptr<float> pranges = &ranges[0, 0];
		return gcnew ManagedHistogram(cvCreateHist(dims, psizes, (int)type, (float**)pranges), true);
	}

	/// <summary>
	/// Creates new histogram
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <returns></returns>
	static ManagedHistogram^ CreateHist(int dims, array<int>^ sizes, HistType type)
	{
		pin_ptr<int> psizes = &sizes[0];
		return gcnew ManagedHistogram(cvCreateHist(dims, psizes, (int)type), true);
	}

	/// <summary>
	/// Assignes histogram bin ranges
	/// </summary>
	/// <param name="hist"></param>
	/// <param name="ranges"></param>
	static void SetHistBinRanges(ManagedHistogram^ hist, array<float, 2>^ ranges, bool uniform)
	{
		pin_ptr<float> pranges = &ranges[0, 0];
		cvSetHistBinRanges(hist->ToCvHistogramPointer(), (float**)pranges, (int)uniform);
	}

	/// <summary>
	/// Assignes histogram bin ranges
	/// </summary>
	/// <param name="hist"></param>
	static void SetHistBinRanges(ManagedHistogram^ hist, array<float, 2>^ ranges)
	{
		pin_ptr<float> pranges = &ranges[0, 0];
		cvSetHistBinRanges(hist->ToCvHistogramPointer(), (float**)pranges);
	}

	/// <summary>
	/// Creates histogram header for array
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="hist"></param>
	/// <param name="data"></param>
	/// <param name="ranges"></param>
	/// <returns></returns>
	static ManagedHistogram^ MakeHistHeaderForArray(int dims, array<int>^ sizes, ManagedHistogram^ hist, array<float>^ data, array<float, 2>^ ranges, bool uniform)
	{
		pin_ptr<int> psizes = &sizes[0];
		pin_ptr<float> pranges = &ranges[0, 0];
		pin_ptr<float> pdata = &data[0];
		return gcnew ManagedHistogram(cvMakeHistHeaderForArray(dims, psizes, hist->ToCvHistogramPointer(), pdata, (float**)pranges, (int)uniform), false);
	}

	/// <summary>
	/// Creates histogram header for array
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="hist"></param>
	/// <param name="data"></param>
	/// <returns></returns>
	static ManagedHistogram^ MakeHistHeaderForArray(int dims, array<int>^ sizes, ManagedHistogram^ hist, array<float>^ data, array<float, 2>^ ranges)
	{
		pin_ptr<int> psizes = &sizes[0];
		pin_ptr<float> pranges = &ranges[0, 0];
		pin_ptr<float> pdata = &data[0];
		return gcnew ManagedHistogram(cvMakeHistHeaderForArray(dims, psizes, hist->ToCvHistogramPointer(), pdata, (float**)pranges), true);
	}

	/// <summary>
	/// Creates histogram header for array
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="hist"></param>
	/// <returns></returns>
	static ManagedHistogram^ MakeHistHeaderForArray(int dims, array<int>^ sizes, ManagedHistogram^ hist, array<float>^ data)
	{
		pin_ptr<int> psizes = &sizes[0];
		pin_ptr<float> pdata = &data[0];
		return gcnew ManagedHistogram(cvMakeHistHeaderForArray(dims, psizes, hist->ToCvHistogramPointer(), pdata), true);
	}

	/// <summary>
	/// Releases histogram
	/// </summary>
	static void ReleaseHist(ManagedHistogram^% hist)
	{
		CvHistogram* pHistogram = hist->ToCvHistogramPointer();
		cvReleaseHist(&pHistogram);
		hist->m_pHandle = pHistogram;
	}

	/// <summary>
	/// Clears all the histogram bins
	/// </summary>
	static void ClearHist(ManagedHistogram^ hist)
	{
		cvClearHist(hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// Finds indices and values of minimum and maximum histogram bins
	/// </summary>
	/// <param name="hist"></param>
	/// <param name="min_value"></param>
	/// <param name="max_value"></param>
	/// <param name="min_idx"></param>
	static void GetMinMaxHistValue(ManagedHistogram^ hist, [OutAttribute] float% min_value, [OutAttribute] float% max_value, [OutAttribute] int% min_idx, [OutAttribute] int% max_idx)
	{
		pin_ptr<float> pmin_value = &min_value;
		pin_ptr<float> pmax_value = &max_value;
		pin_ptr<int> pmin_idx = &min_idx;
		pin_ptr<int> pmax_idx = &max_idx;
		cvGetMinMaxHistValue(hist->ToCvHistogramPointer(), pmin_value, pmax_value, pmin_idx, pmax_idx);
	}

	/// <summary>
	/// Finds indices and values of minimum and maximum histogram bins
	/// </summary>
	/// <param name="hist"></param>
	/// <param name="min_value"></param>
	/// <param name="max_value"></param>
	static void GetMinMaxHistValue(ManagedHistogram^ hist, [OutAttribute] float% min_value, [OutAttribute] float% max_value, [OutAttribute] int% min_idx)
	{
		pin_ptr<float> pmin_value = &min_value;
		pin_ptr<float> pmax_value = &max_value;
		pin_ptr<int> pmin_idx = &min_idx;
		cvGetMinMaxHistValue(hist->ToCvHistogramPointer(), pmin_value, pmax_value, pmin_idx);
	}

	/// <summary>
	/// Finds indices and values of minimum and maximum histogram bins
	/// </summary>
	/// <param name="hist"></param>
	/// <param name="min_value"></param>
	static void GetMinMaxHistValue(ManagedHistogram^ hist, [OutAttribute] float% min_value, [OutAttribute] float% max_value)
	{
		pin_ptr<float> pmin_value = &min_value;
		pin_ptr<float> pmax_value = &max_value;
		cvGetMinMaxHistValue(hist->ToCvHistogramPointer(), pmin_value, pmax_value);
	}

	/// <summary>
	/// Normalizes histogram by dividing all bins by sum of the bins, multiplied by <factor>.
	/// After that sum of histogram bins is equal to <factor>
	/// </summary>
	/// <param name="hist"></param>
	static void NormalizeHist(ManagedHistogram^ hist, double factor)
	{
		cvNormalizeHist(hist->ToCvHistogramPointer(), factor);
	}

	/// <summary>
	/// Clear all histogram bins that are below the threshold
	/// </summary>
	/// <param name="hist"></param>
	static void ThreshHist(ManagedHistogram^ hist, double threshold)
	{
		cvThreshHist(hist->ToCvHistogramPointer(), threshold);
	}

	/// <summary>
	/// Compares two histogram
	/// </summary>
	/// <param name="hist1"></param>
	/// <param name="hist2"></param>
	/// <returns></returns>
	static double CompareHist(ManagedHistogram^ hist1, ManagedHistogram^ hist2, CompareHistMethod method)
	{
		return cvCompareHist(hist1->ToCvHistogramPointer(), hist2->ToCvHistogramPointer(), (int)method);
	}

	/// <summary>
	/// Copies one histogram to another. Destination histogram is created if
	/// the destination pointer is NULL
	/// </summary>
	/// <param name="src"></param>
	static void CopyHist(ManagedHistogram^ src, ManagedHistogram^% dst)
	{
		CvHistogram* phistogram = (dst == nullptr) ? NULL : dst->ToCvHistogramPointer();
		cvCopyHist((CvHistogram*)src->ToCvHistogramPointer(), &phistogram);
		if (!dst->IsValid)
		{
			dst->m_pHandle = phistogram;
		}
	}

	/// <summary>
	/// Calculates bayesian probabilistic histograms
	/// (each or src and dst is an array of <number> histograms
	/// </summary>
	/// <param name="src"></param>
	/// <param name="number"></param>
	static void CalcBayesianProb(array<ManagedHistogram^>^ src, int number, array<ManagedHistogram^>^ dst)
	{
		vector<CvHistogram*> vsrc(number);
		vector<CvHistogram*> vdst(number);
		for (int i = 0; i < number; i++)
		{
			vsrc[i] = src[i]->ToCvHistogramPointer();
			vdst[i] = dst[i]->ToCvHistogramPointer();
		}
		cvCalcBayesianProb(&vsrc[0], number, &vdst[0]);
	}

	/// <summary>
	/// Calculates array histogram
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="hist"></param>
	/// <param name="accumulate"></param>
	static void CalcArrHist(array<ManagedArr^>^ arr, ManagedHistogram^ hist, bool accumulate, ManagedArr^ mask)
	{
		vector<CvArr*> varr(arr->Length);
		for (int i = 0; i < arr->Length; i++)
		{
			varr[i] = arr[i]->ToCvArrPointer();
		}
		cvCalcArrHist(&varr[0], hist->ToCvHistogramPointer(), (int)accumulate, mask->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates array histogram
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="hist"></param>
	static void CalcArrHist(array<ManagedArr^>^ arr, ManagedHistogram^ hist, bool accumulate)
	{
		vector<CvArr*> varr(arr->Length);
		for (int i = 0; i < arr->Length; i++)
		{
			varr[i] = arr[i]->ToCvArrPointer();
		}
		cvCalcArrHist(&varr[0], hist->ToCvHistogramPointer(), (int)accumulate);
	}

	/// <summary>
	/// Calculates array histogram
	/// </summary>
	/// <param name="arr"></param>
	static void CalcArrHist(array<ManagedArr^>^ arr, ManagedHistogram^ hist)
	{
		vector<CvArr*> varr(arr->Length);
		for (int i = 0; i < arr->Length; i++)
		{
			varr[i] = arr[i]->ToCvArrPointer();
		}
		cvCalcArrHist(&varr[0], hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// Calculates back project
	/// </summary>
	/// <param name="image"></param>
	/// <param name="dst"></param>
	static void CalcArrBackProject(array<ManagedArr^>^ image, ManagedArr^ dst, ManagedHistogram^ hist)
	{
		vector<CvArr*> vimage(image->Length);
		for (int i = 0; i < image->Length; i++)
		{
			vimage[i] = image[i]->ToCvArrPointer();
		}
		cvCalcArrBackProject(&vimage[0], dst->ToCvArrPointer(), hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// Calculates back project
	/// </summary>
	/// <param name="image"></param>
	/// <param name="dst"></param>
	static void CalcBackProject(array<ManagedArr^>^ image, ManagedArr^ dst, ManagedHistogram^ hist)
	{
		vector<CvArr*> vimage(image->Length);
		for (int i = 0; i < image->Length; i++)
		{
			vimage[i] = image[i]->ToCvArrPointer();
		}
		cvCalcBackProject(&vimage[0], dst->ToCvArrPointer(), hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// Does some sort of template matching but compares histograms of
	/// template and each window location
	/// </summary>
	/// <param name="image"></param>
	/// <param name="dst"></param>
	/// <param name="range"></param>
	/// <param name="hist"></param>
	/// <param name="method"></param>
	static void CalcArrBackProjectPatch(array<ManagedArr^>^ image, ManagedArr^ dst, NAMESPACE::Size2D32s range, ManagedHistogram^ hist, CompareHistMethod method, double factor)
	{
		vector<CvArr*> vimage(image->Length);
		for (int i = 0; i < image->Length; i++)
		{
			vimage[i] = image[i]->ToCvArrPointer();
		}
		cvCalcArrBackProjectPatch(&vimage[0], dst->ToCvArrPointer(), *(CvSize*)&range, hist->ToCvHistogramPointer(), (int)method, factor);
	}

	/// <summary>
	/// Does some sort of template matching but compares histograms of
	/// template and each window location
	/// </summary>
	/// <param name="image"></param>
	/// <param name="dst"></param>
	/// <param name="range"></param>
	/// <param name="hist"></param>
	/// <param name="method"></param>
	static void CalcBackProjectPatch(array<ManagedArr^>^ image, ManagedArr^ dst, NAMESPACE::Size2D32s range, ManagedHistogram^ hist, CompareHistMethod method, double factor)
	{
		vector<CvArr*> vimage(image->Length);
		for (int i = 0; i < image->Length; i++)
		{
			vimage[i] = image[i]->ToCvArrPointer();
		}
		cvCalcBackProjectPatch(&vimage[0], dst->ToCvArrPointer(), *(CvSize*)&range, hist->ToCvHistogramPointer(), (int)method, factor);
	}

	/// <summary>
	/// calculates probabilistic density (divides one histogram by another)
	/// </summary>
	/// <param name="hist1"></param>
	/// <param name="hist2"></param>
	/// <param name="dst_hist"></param>
	static void CalcProbDensity(ManagedHistogram^ hist1, ManagedHistogram^ hist2, ManagedHistogram^ dst_hist, double scale)
	{
		cvCalcProbDensity(hist1->ToCvHistogramPointer(), hist2->ToCvHistogramPointer(), dst_hist->ToCvHistogramPointer(), scale);
	}

	/// <summary>
	/// calculates probabilistic density (divides one histogram by another)
	/// </summary>
	/// <param name="hist1"></param>
	/// <param name="hist2"></param>
	static void CalcProbDensity(ManagedHistogram^ hist1, ManagedHistogram^ hist2, ManagedHistogram^ dst_hist)
	{
		cvCalcProbDensity(hist1->ToCvHistogramPointer(), hist2->ToCvHistogramPointer(), dst_hist->ToCvHistogramPointer());
	}

	/// <summary>
	/// equalizes histogram of 8-bit single-channel image
	/// </summary>
	/// <param name="src"></param>
	static void EqualizeHist(ManagedArr^ src, ManagedArr^ dst)
	{
		cvEqualizeHist(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Updates active contour in order to minimize its cummulative
	/// (internal and external) energy.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="points"></param>
	/// <param name="length"></param>
	/// <param name="alpha"></param>
	/// <param name="beta"></param>
	/// <param name="gamma"></param>
	/// <param name="coeff_usage"></param>
	/// <param name="win"></param>
	/// <param name="criteria"></param>
	static void SnakeImage(ManagedImage^ image, array<NAMESPACE::Point2D32s>^ points, int length, array<float>^ alpha, array<float>^ beta, array<float>^ gamma, CoeffUsageType coeff_usage, NAMESPACE::Size2D32s win, NAMESPACE::TermCriteria criteria, bool calc_gradient)
	{
		pin_ptr<NAMESPACE::Point2D32s> ppoints = &points[0];
		pin_ptr<float> palpha = &alpha[0];
		pin_ptr<float> pbeta = &beta[0];
		pin_ptr<float> pgamma = &gamma[0];
		cvSnakeImage(image->ToIplImagePointer(), (CvPoint*)ppoints, length, palpha, pbeta, pgamma, (int)coeff_usage, *(CvSize*)&win, *(CvTermCriteria*)&criteria, (int)calc_gradient);
	}

	/// <summary>
	/// Updates active contour in order to minimize its cummulative
	/// (internal and external) energy.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="points"></param>
	/// <param name="length"></param>
	/// <param name="alpha"></param>
	/// <param name="beta"></param>
	/// <param name="gamma"></param>
	/// <param name="coeff_usage"></param>
	/// <param name="win"></param>
	static void SnakeImage(ManagedImage^ image, array<NAMESPACE::Point2D32s>^ points, int length, array<float>^ alpha, array<float>^ beta, array<float>^ gamma, CoeffUsageType coeff_usage, NAMESPACE::Size2D32s win, NAMESPACE::TermCriteria criteria)
	{
		pin_ptr<NAMESPACE::Point2D32s> ppoints = &points[0];
		pin_ptr<float> palpha = &alpha[0];
		pin_ptr<float> pbeta = &beta[0];
		pin_ptr<float> pgamma = &gamma[0];
		cvSnakeImage(image->ToIplImagePointer(), (CvPoint*)ppoints, length, palpha, pbeta, pgamma, (int)coeff_usage, *(CvSize*)&win, *(CvTermCriteria*)&criteria);
	}

	/// <summary>
	/// Calculates the cooficients of the homography matrix
	/// </summary>
	/// <param name="line"></param>
	/// <param name="center"></param>
	/// <param name="intrinsic"></param>
	static void CalcImageHomography(array<float>^ line, NAMESPACE::Point3D32f% center, array<float>^ intrinsic, array<float>^ homography)
	{
		pin_ptr<float> pline = &line[0];
		pin_ptr<NAMESPACE::Point3D32f> pcenter = &center;
		pin_ptr<float> pintrinsic = &intrinsic[0];
		pin_ptr<float> phomography = &homography[0];
		cvCalcImageHomography(pline, (CvPoint3D32f*)pcenter, pintrinsic, phomography);
	}

	/// <summary>
	/// Applies distance transform to binary image
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="distance_type"></param>
	/// <param name="mask_size"></param>
	/// <param name="mask"></param>
	static void DistTransform(ManagedArr^ src, ManagedArr^ dst, DistanceType distance_type, DistanceTransformMask mask_size, array<float>^ mask, ManagedArr^ labels)
	{
		pin_ptr<float> pmask = &mask[0];
		cvDistTransform(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)distance_type, (int)mask_size, pmask, labels->ToCvArrPointer());
	}

	/// <summary>
	/// Applies distance transform to binary image
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="distance_type"></param>
	/// <param name="mask_size"></param>
	static void DistTransform(ManagedArr^ src, ManagedArr^ dst, DistanceType distance_type, DistanceTransformMask mask_size, array<float>^ mask)
	{
		pin_ptr<float> pmask = &mask[0];
		cvDistTransform(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)distance_type, (int)mask_size, pmask);
	}

	/// <summary>
	/// Applies distance transform to binary image
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="distance_type"></param>
	static void DistTransform(ManagedArr^ src, ManagedArr^ dst, DistanceType distance_type, DistanceTransformMask mask_size)
	{
		cvDistTransform(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)distance_type, (int)mask_size);
	}

	/// <summary>
	/// Applies distance transform to binary image
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void DistTransform(ManagedArr^ src, ManagedArr^ dst, DistanceType distance_type)
	{
		cvDistTransform(src->ToCvArrPointer(), dst->ToCvArrPointer(), (int)distance_type);
	}

	/// <summary>
	/// Applies distance transform to binary image
	/// </summary>
	/// <param name="src"></param>
	static void DistTransform(ManagedArr^ src, ManagedArr^ dst)
	{
		cvDistTransform(src->ToCvArrPointer(), dst->ToCvArrPointer());
	}

	/// <summary>
	/// Applies fixed-level threshold to grayscale image.
	/// This is a basic operation applied before retrieving contours
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="threshold"></param>
	/// <param name="max_value"></param>
	/// <returns></returns>
	static double Threshold(ManagedArr^ src, ManagedArr^ dst, double threshold, double max_value, ThreshTypeFlag threshold_type)
	{
		return cvThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), threshold, max_value, (int)threshold_type);
	}

	/// <summary>
	/// Applies adaptive threshold to grayscale image.
	/// The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
	/// CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
	/// neighborhood size (3, 5, 7 etc.),
	/// and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="max_value"></param>
	/// <param name="adaptive_method"></param>
	/// <param name="threshold_type"></param>
	/// <param name="block_size"></param>
	static void AdaptiveThreshold(ManagedArr^ src, ManagedArr^ dst, double max_value, AdaptiveThreshMethod adaptive_method, ThreshTypeFlag threshold_type, int block_size, double param1)
	{
		cvAdaptiveThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), max_value, (int)adaptive_method, (int)threshold_type, block_size, param1);
	}

	/// <summary>
	/// Applies adaptive threshold to grayscale image.
	/// The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
	/// CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
	/// neighborhood size (3, 5, 7 etc.),
	/// and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="max_value"></param>
	/// <param name="adaptive_method"></param>
	/// <param name="threshold_type"></param>
	static void AdaptiveThreshold(ManagedArr^ src, ManagedArr^ dst, double max_value, AdaptiveThreshMethod adaptive_method, ThreshTypeFlag threshold_type, int block_size)
	{
		cvAdaptiveThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), max_value, (int)adaptive_method, (int)threshold_type, block_size);
	}

	/// <summary>
	/// Applies adaptive threshold to grayscale image.
	/// The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
	/// CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
	/// neighborhood size (3, 5, 7 etc.),
	/// and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="max_value"></param>
	/// <param name="adaptive_method"></param>
	static void AdaptiveThreshold(ManagedArr^ src, ManagedArr^ dst, double max_value, AdaptiveThreshMethod adaptive_method, ThreshTypeFlag threshold_type)
	{
		cvAdaptiveThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), max_value, (int)adaptive_method, (int)threshold_type);
	}

	/// <summary>
	/// Applies adaptive threshold to grayscale image.
	/// The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
	/// CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
	/// neighborhood size (3, 5, 7 etc.),
	/// and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="max_value"></param>
	static void AdaptiveThreshold(ManagedArr^ src, ManagedArr^ dst, double max_value, AdaptiveThreshMethod adaptive_method)
	{
		cvAdaptiveThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), max_value, (int)adaptive_method);
	}

	/// <summary>
	/// Applies adaptive threshold to grayscale image.
	/// The two parameters for methods CV_ADAPTIVE_THRESH_MEAN_C and
	/// CV_ADAPTIVE_THRESH_GAUSSIAN_C are:
	/// neighborhood size (3, 5, 7 etc.),
	/// and a constant subtracted from mean (...,-3,-2,-1,0,1,2,3,...)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void AdaptiveThreshold(ManagedArr^ src, ManagedArr^ dst, double max_value)
	{
		cvAdaptiveThreshold(src->ToCvArrPointer(), dst->ToCvArrPointer(), max_value);
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	/// <param name="new_val"></param>
	/// <param name="lo_diff"></param>
	/// <param name="up_diff"></param>
	/// <param name="comp"></param>
	/// <param name="flags"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val, NAMESPACE::Scalar lo_diff, NAMESPACE::Scalar up_diff, ManagedConnectedComp^ comp, FloodFillFlag flags, ManagedArr^ mask)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val, *(CvScalar*)&lo_diff, *(CvScalar*)&up_diff, comp->ToConnectedCompPointer(), (int)flags, mask->ToCvArrPointer());
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	/// <param name="new_val"></param>
	/// <param name="lo_diff"></param>
	/// <param name="up_diff"></param>
	/// <param name="comp"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val, NAMESPACE::Scalar lo_diff, NAMESPACE::Scalar up_diff, ManagedConnectedComp^ comp, FloodFillFlag flags)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val, *(CvScalar*)&lo_diff, *(CvScalar*)&up_diff, comp->ToConnectedCompPointer(), (int)flags);
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	/// <param name="new_val"></param>
	/// <param name="lo_diff"></param>
	/// <param name="up_diff"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val, NAMESPACE::Scalar lo_diff, NAMESPACE::Scalar up_diff, ManagedConnectedComp^ comp)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val, *(CvScalar*)&lo_diff, *(CvScalar*)&up_diff, comp->ToConnectedCompPointer());
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	/// <param name="new_val"></param>
	/// <param name="lo_diff"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val, NAMESPACE::Scalar lo_diff, NAMESPACE::Scalar up_diff)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val, *(CvScalar*)&lo_diff, *(CvScalar*)&up_diff);
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	/// <param name="new_val"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val, NAMESPACE::Scalar lo_diff)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val, *(CvScalar*)&lo_diff);
	}

	/// <summary>
	/// Fills the connected component until the color difference gets large enough
	/// </summary>
	/// <param name="image"></param>
	/// <param name="seed_point"></param>
	static void FloodFill(ManagedArr^ image, NAMESPACE::Point2D32s seed_point, NAMESPACE::Scalar new_val)
	{
		cvFloodFill(image->ToCvArrPointer(), *(CvPoint*)&seed_point, *(CvScalar*)&new_val);
	}

	/// <summary>
	/// Runs canny edge detector
	/// </summary>
	/// <param name="image"></param>
	/// <param name="edges"></param>
	/// <param name="threshold1"></param>
	/// <param name="threshold2"></param>
	static void Canny(ManagedArr^ image, ManagedArr^ edges, double threshold1, double threshold2, ApertureSize aperture_size)
	{
		cvCanny(image->ToCvArrPointer(), edges->ToCvArrPointer(), threshold1, threshold2, (int)aperture_size);
	}

	/// <summary>
	/// Runs canny edge detector
	/// </summary>
	/// <param name="image"></param>
	/// <param name="edges"></param>
	/// <param name="threshold1"></param>
	static void Canny(ManagedArr^ image, ManagedArr^ edges, double threshold1, double threshold2)
	{
		cvCanny(image->ToCvArrPointer(), edges->ToCvArrPointer(), threshold1, threshold2);
	}

	/// <summary>
	/// Calculates constraint image for corner detection
	/// Dx^2 * Dyy + Dxx * Dy^2 - 2 * Dx * Dy * Dxy.
	/// Applying threshold to the result gives coordinates of corners
	/// </summary>
	/// <param name="image"></param>
	/// <param name="corners"></param>
	static void PreCornerDetect(ManagedArr^ image, ManagedArr^ corners, ApertureSize aperture_size)
	{
		cvPreCornerDetect(image->ToCvArrPointer(), corners->ToCvArrPointer(), (int)aperture_size);
	}

	/// <summary>
	/// Calculates constraint image for corner detection
	/// Dx^2 * Dyy + Dxx * Dy^2 - 2 * Dx * Dy * Dxy.
	/// Applying threshold to the result gives coordinates of corners
	/// </summary>
	/// <param name="image"></param>
	static void PreCornerDetect(ManagedArr^ image, ManagedArr^ corners)
	{
		cvPreCornerDetect(image->ToCvArrPointer(), corners->ToCvArrPointer());
	}

	/// <summary>
	/// Calculates eigen values and vectors of 2x2
	/// gradient covariation matrix at every image pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eigenvv"></param>
	/// <param name="block_size"></param>
	static void CornerEigenValsAndVecs(ManagedArr^ image, ManagedArr^ eigenvv, int block_size, ApertureSize aperture_size)
	{
		cvCornerEigenValsAndVecs(image->ToCvArrPointer(), eigenvv->ToCvArrPointer(), block_size, (int)aperture_size);
	}

	/// <summary>
	/// Calculates eigen values and vectors of 2x2
	/// gradient covariation matrix at every image pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eigenvv"></param>
	static void CornerEigenValsAndVecs(ManagedArr^ image, ManagedArr^ eigenvv, int block_size)
	{
		cvCornerEigenValsAndVecs(image->ToCvArrPointer(), eigenvv->ToCvArrPointer(), block_size);
	}

	/// <summary>
	/// Calculates minimal eigenvalue for 2x2 gradient covariation matrix at
	/// every image pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eigenval"></param>
	/// <param name="block_size"></param>
	static void CornerMinEigenVal(ManagedArr^ image, ManagedArr^ eigenval, int block_size, ApertureSize aperture_size)
	{
		cvCornerMinEigenVal(image->ToCvArrPointer(), eigenval->ToCvArrPointer(), block_size, (int)aperture_size);
	}

	/// <summary>
	/// Calculates minimal eigenvalue for 2x2 gradient covariation matrix at
	/// every image pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eigenval"></param>
	static void CornerMinEigenVal(ManagedArr^ image, ManagedArr^ eigenval, int block_size)
	{
		cvCornerMinEigenVal(image->ToCvArrPointer(), eigenval->ToCvArrPointer(), block_size);
	}

	/// <summary>
	/// Harris corner detector:
	/// Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="harris_responce"></param>
	/// <param name="block_size"></param>
	/// <param name="aperture_size"></param>
	static void CornerHarris(ManagedArr^ image, ManagedArr^ harris, int block_size, ApertureSize aperture_size, double k)
	{
		cvCornerHarris(image->ToCvArrPointer(), harris->ToCvArrPointer(), block_size, (int)aperture_size, k);
	}

	/// <summary>
	/// Harris corner detector:
	/// Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="harris_responce"></param>
	/// <param name="block_size"></param>
	static void CornerHarris(ManagedArr^ image, ManagedArr^ harris, int block_size, ApertureSize aperture_size)
	{
		cvCornerHarris(image->ToCvArrPointer(), harris->ToCvArrPointer(), block_size, (int)aperture_size);
	}

	/// <summary>
	/// Harris corner detector:
	/// Calculates det(M) - k*(trace(M)^2), where M is 2x2 gradient covariation matrix for each pixel
	/// </summary>
	/// <param name="image"></param>
	/// <param name="harris_responce"></param>
	static void CornerHarris(ManagedArr^ image, ManagedArr^ harris, int block_size)
	{
		cvCornerHarris(image->ToCvArrPointer(), harris->ToCvArrPointer(), block_size);
	}

	/// <summary>
	/// Adjust corner position using some sort of gradient search
	/// </summary>
	/// <param name="image"></param>
	/// <param name="corners"></param>
	/// <param name="count"></param>
	/// <param name="win"></param>
	/// <param name="zero_zone"></param>
	static void FindCornerSubPix(ManagedArr^ image, array<NAMESPACE::Point2D32f>^ corners, int count, NAMESPACE::Size2D32s win, NAMESPACE::Size2D32s zero_zone, NAMESPACE::TermCriteria criteria)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		cvFindCornerSubPix(image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, count, *(CvSize*)&win, *(CvSize*)&zero_zone, *(CvTermCriteria*)&criteria);
	}

	/// <summary>
	/// Finds a sparse set of points within the selected region
	/// that seem to be easy to track
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eig_image"></param>
	/// <param name="temp_image"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <param name="quality_level"></param>
	/// <param name="min_distance"></param>
	/// <param name="mask"></param>
	/// <param name="block_size"></param>
	/// <param name="use_harris"></param>
	static void GoodFeaturesToTrack(ManagedArr^ image, ManagedArr^ eig_image, ManagedArr^ temp_image, array<NAMESPACE::Point2D32f>^ corners, int% corner_count, double quality_level, double min_distance, ManagedArr^ mask, int block_size, bool use_harris, double k)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		cvGoodFeaturesToTrack(image->ToCvArrPointer(), eig_image->ToCvArrPointer(), temp_image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, pcorner_count, quality_level, min_distance, mask->ToCvArrPointer(), block_size, (int)use_harris, k);
	}

	/// <summary>
	/// Finds a sparse set of points within the selected region
	/// that seem to be easy to track
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eig_image"></param>
	/// <param name="temp_image"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <param name="quality_level"></param>
	/// <param name="min_distance"></param>
	/// <param name="mask"></param>
	/// <param name="block_size"></param>
	static void GoodFeaturesToTrack(ManagedArr^ image, ManagedArr^ eig_image, ManagedArr^ temp_image, array<NAMESPACE::Point2D32f>^ corners, int% corner_count, double quality_level, double min_distance, ManagedArr^ mask, int block_size, bool use_harris)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		cvGoodFeaturesToTrack(image->ToCvArrPointer(), eig_image->ToCvArrPointer(), temp_image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, pcorner_count, quality_level, min_distance, mask->ToCvArrPointer(), block_size, (int)use_harris);
	}

	/// <summary>
	/// Finds a sparse set of points within the selected region
	/// that seem to be easy to track
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eig_image"></param>
	/// <param name="temp_image"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <param name="quality_level"></param>
	/// <param name="min_distance"></param>
	/// <param name="mask"></param>
	static void GoodFeaturesToTrack(ManagedArr^ image, ManagedArr^ eig_image, ManagedArr^ temp_image, array<NAMESPACE::Point2D32f>^ corners, int% corner_count, double quality_level, double min_distance, ManagedArr^ mask, int block_size)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		cvGoodFeaturesToTrack(image->ToCvArrPointer(), eig_image->ToCvArrPointer(), temp_image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, pcorner_count, quality_level, min_distance, mask->ToCvArrPointer(), block_size);
	}

	/// <summary>
	/// Finds a sparse set of points within the selected region
	/// that seem to be easy to track
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eig_image"></param>
	/// <param name="temp_image"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <param name="quality_level"></param>
	/// <param name="min_distance"></param>
	static void GoodFeaturesToTrack(ManagedArr^ image, ManagedArr^ eig_image, ManagedArr^ temp_image, array<NAMESPACE::Point2D32f>^ corners, int% corner_count, double quality_level, double min_distance, ManagedArr^ mask)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		cvGoodFeaturesToTrack(image->ToCvArrPointer(), eig_image->ToCvArrPointer(), temp_image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, pcorner_count, quality_level, min_distance, mask->ToCvArrPointer());
	}

	/// <summary>
	/// Finds a sparse set of points within the selected region
	/// that seem to be easy to track
	/// </summary>
	/// <param name="image"></param>
	/// <param name="eig_image"></param>
	/// <param name="temp_image"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <param name="quality_level"></param>
	static void GoodFeaturesToTrack(ManagedArr^ image, ManagedArr^ eig_image, ManagedArr^ temp_image, array<NAMESPACE::Point2D32f>^ corners, int% corner_count, double quality_level, double min_distance)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		cvGoodFeaturesToTrack(image->ToCvArrPointer(), eig_image->ToCvArrPointer(), temp_image->ToCvArrPointer(), (CvPoint2D32f*)pcorners, pcorner_count, quality_level, min_distance);
	}

	/// <summary>
	/// Finds lines on binary image using one of several methods.
	/// line_storage is either memory storage or 1 x <max number of lines> CvMat, its
	/// number of columns is changed by the function.
	/// method is one of CV_HOUGH_*;
	/// rho, theta and threshold are used for each of those methods;
	/// param1 ~ line length, param2 ~ line gap - for probabilistic,
	/// param1 ~ srn, param2 ~ stn - for multi-scale
	/// </summary>
	/// <param name="image"></param>
	/// <param name="line_storage"></param>
	/// <param name="method"></param>
	/// <param name="rho"></param>
	/// <param name="theta"></param>
	/// <param name="threshold"></param>
	/// <param name="param1"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughLines2(ManagedArr^ image, NativeHandleObject^ line_storage, HoughMethod method, double rho, double theta, int threshold, double param1, double param2)
	{
		return gcnew ManagedSeq(cvHoughLines2(image->ToCvArrPointer(), line_storage->ToNativePointer(), (int)method, rho, theta, threshold, param1, param2));
	}

	/// <summary>
	/// Finds lines on binary image using one of several methods.
	/// line_storage is either memory storage or 1 x <max number of lines> CvMat, its
	/// number of columns is changed by the function.
	/// method is one of CV_HOUGH_*;
	/// rho, theta and threshold are used for each of those methods;
	/// param1 ~ line length, param2 ~ line gap - for probabilistic,
	/// param1 ~ srn, param2 ~ stn - for multi-scale
	/// </summary>
	/// <param name="image"></param>
	/// <param name="line_storage"></param>
	/// <param name="method"></param>
	/// <param name="rho"></param>
	/// <param name="theta"></param>
	/// <param name="threshold"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughLines2(ManagedArr^ image, NativeHandleObject^ line_storage, HoughMethod method, double rho, double theta, int threshold, double param1)
	{
		return gcnew ManagedSeq(cvHoughLines2(image->ToCvArrPointer(), line_storage->ToNativePointer(), (int)method, rho, theta, threshold, param1));
	}

	/// <summary>
	/// Finds lines on binary image using one of several methods.
	/// line_storage is either memory storage or 1 x <max number of lines> CvMat, its
	/// number of columns is changed by the function.
	/// method is one of CV_HOUGH_*;
	/// rho, theta and threshold are used for each of those methods;
	/// param1 ~ line length, param2 ~ line gap - for probabilistic,
	/// param1 ~ srn, param2 ~ stn - for multi-scale
	/// </summary>
	/// <param name="image"></param>
	/// <param name="line_storage"></param>
	/// <param name="method"></param>
	/// <param name="rho"></param>
	/// <param name="theta"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughLines2(ManagedArr^ image, NativeHandleObject^ line_storage, HoughMethod method, double rho, double theta, int threshold)
	{
		return gcnew ManagedSeq(cvHoughLines2(image->ToCvArrPointer(), line_storage->ToNativePointer(), (int)method, rho, theta, threshold));
	}

	/// <summary>
	/// Finds circles in the image
	/// </summary>
	/// <param name="image"></param>
	/// <param name="circle_storage"></param>
	/// <param name="method"></param>
	/// <param name="dp"></param>
	/// <param name="min_dist"></param>
	/// <param name="param1"></param>
	/// <param name="param2"></param>
	/// <param name="min_radius"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughCircles(ManagedArr^ image, NativeHandleObject^ circle_storage, HoughMethod method, double dp, double min_dist, double param1, double param2, int min_radius, int max_radius)
	{
		return gcnew ManagedSeq(cvHoughCircles(image->ToCvArrPointer(), circle_storage->ToNativePointer(), (int)method, dp, min_dist, param1, param2, min_radius, max_radius));
	}

	/// <summary>
	/// Finds circles in the image
	/// </summary>
	/// <param name="image"></param>
	/// <param name="circle_storage"></param>
	/// <param name="method"></param>
	/// <param name="dp"></param>
	/// <param name="min_dist"></param>
	/// <param name="param1"></param>
	/// <param name="param2"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughCircles(ManagedArr^ image, NativeHandleObject^ circle_storage, HoughMethod method, double dp, double min_dist, double param1, double param2, int min_radius)
	{
		return gcnew ManagedSeq(cvHoughCircles(image->ToCvArrPointer(), circle_storage->ToNativePointer(), (int)method, dp, min_dist, param1, param2, min_radius));
	}

	/// <summary>
	/// Finds circles in the image
	/// </summary>
	/// <param name="image"></param>
	/// <param name="circle_storage"></param>
	/// <param name="method"></param>
	/// <param name="dp"></param>
	/// <param name="min_dist"></param>
	/// <param name="param1"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughCircles(ManagedArr^ image, NativeHandleObject^ circle_storage, HoughMethod method, double dp, double min_dist, double param1, double param2)
	{
		return gcnew ManagedSeq(cvHoughCircles(image->ToCvArrPointer(), circle_storage->ToNativePointer(), (int)method, dp, min_dist, param1, param2));
	}

	/// <summary>
	/// Finds circles in the image
	/// </summary>
	/// <param name="image"></param>
	/// <param name="circle_storage"></param>
	/// <param name="method"></param>
	/// <param name="dp"></param>
	/// <param name="min_dist"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughCircles(ManagedArr^ image, NativeHandleObject^ circle_storage, HoughMethod method, double dp, double min_dist, double param1)
	{
		return gcnew ManagedSeq(cvHoughCircles(image->ToCvArrPointer(), circle_storage->ToNativePointer(), (int)method, dp, min_dist, param1));
	}

	/// <summary>
	/// Finds circles in the image
	/// </summary>
	/// <param name="image"></param>
	/// <param name="circle_storage"></param>
	/// <param name="method"></param>
	/// <param name="dp"></param>
	/// <returns></returns>
	static ManagedSeq^ HoughCircles(ManagedArr^ image, NativeHandleObject^ circle_storage, HoughMethod method, double dp, double min_dist)
	{
		return gcnew ManagedSeq(cvHoughCircles(image->ToCvArrPointer(), circle_storage->ToNativePointer(), (int)method, dp, min_dist));
	}

	/// <summary>
	/// Fits a line into set of 2d or 3d points in a robust way (M-estimator technique)
	/// </summary>
	/// <param name="points"></param>
	/// <param name="dist_type"></param>
	/// <param name="param"></param>
	/// <param name="reps"></param>
	/// <param name="aeps"></param>
	static void FitLine(ManagedArr^ points, DistanceType dist_type, double param, double reps, double aeps, array<float>^ line)
	{
		pin_ptr<float> pline = &line[0];
		cvFitLine(points->ToCvArrPointer(), (int)dist_type, param, reps, aeps, pline);
	}

	/// <summary>
	/// Constructs kd-tree from set of feature descriptors
	/// </summary>
	/// <returns></returns>
	static ManagedFeatureTree^ CreateKDTree(ManagedMat^ desc)
	{
		return gcnew ManagedFeatureTree(cvCreateKDTree(desc->ToCvMatPointer()), true);
	}

	/// <summary>
	/// Constructs spill-tree from set of feature descriptors
	/// </summary>
	/// <param name="raw_data"></param>
	/// <param name="naive"></param>
	/// <param name="rho"></param>
	/// <returns></returns>
	static ManagedFeatureTree^ CreateSpillTree(ManagedMat^ raw_data, int naive, double rho, double tau)
	{
		return gcnew ManagedFeatureTree(cvCreateSpillTree(raw_data->ToCvMatPointer(), naive, rho, tau), true);
	}

	/// <summary>
	/// Constructs spill-tree from set of feature descriptors
	/// </summary>
	/// <param name="raw_data"></param>
	/// <param name="naive"></param>
	/// <returns></returns>
	static ManagedFeatureTree^ CreateSpillTree(ManagedMat^ raw_data, int naive, double rho)
	{
		return gcnew ManagedFeatureTree(cvCreateSpillTree(raw_data->ToCvMatPointer(), naive, rho), true);
	}

	/// <summary>
	/// Constructs spill-tree from set of feature descriptors
	/// </summary>
	/// <param name="raw_data"></param>
	/// <returns></returns>
	static ManagedFeatureTree^ CreateSpillTree(ManagedMat^ raw_data, int naive)
	{
		return gcnew ManagedFeatureTree(cvCreateSpillTree(raw_data->ToCvMatPointer(), naive), true);
	}

	/// <summary>
	/// Constructs spill-tree from set of feature descriptors
	/// </summary>
	/// <returns></returns>
	static ManagedFeatureTree^ CreateSpillTree(ManagedMat^ raw_data)
	{
		return gcnew ManagedFeatureTree(cvCreateSpillTree(raw_data->ToCvMatPointer()), true);
	}

	/// <summary>
	/// Release feature tree
	/// </summary>
	static void ReleaseFeatureTree(ManagedFeatureTree^% tr)
	{
		CvFeatureTree* pFeatureTree = tr->ToCvFeatureTreePointer();
		cvReleaseFeatureTree(pFeatureTree);
		tr->m_pHandle = NULL;
	}

	/// <summary>
	/// Searches feature tree for k nearest neighbors of given reference points,
	/// searching (in case of kd-tree/bbf) at most emax leaves.
	/// </summary>
	/// <param name="tr"></param>
	/// <param name="query_points"></param>
	/// <param name="indices"></param>
	/// <param name="dist"></param>
	/// <param name="k"></param>
	static void FindFeatures(ManagedFeatureTree^ tr, ManagedMat^ query_points, ManagedMat^ indices, ManagedMat^ dist, int k, int emax)
	{
		cvFindFeatures(tr->ToCvFeatureTreePointer(), query_points->ToCvMatPointer(), indices->ToCvMatPointer(), dist->ToCvMatPointer(), k, emax);
	}

	/// <summary>
	/// Searches feature tree for k nearest neighbors of given reference points,
	/// searching (in case of kd-tree/bbf) at most emax leaves.
	/// </summary>
	/// <param name="tr"></param>
	/// <param name="query_points"></param>
	/// <param name="indices"></param>
	/// <param name="dist"></param>
	static void FindFeatures(ManagedFeatureTree^ tr, ManagedMat^ query_points, ManagedMat^ indices, ManagedMat^ dist, int k)
	{
		cvFindFeatures(tr->ToCvFeatureTreePointer(), query_points->ToCvMatPointer(), indices->ToCvMatPointer(), dist->ToCvMatPointer(), k);
	}

	/// <summary>
	/// Search feature tree for all points that are inlier to given rect region.
	/// Only implemented for kd trees
	/// </summary>
	/// <param name="tr"></param>
	/// <param name="bounds_min"></param>
	/// <param name="bounds_max"></param>
	/// <returns></returns>
	static int FindFeaturesBoxed(ManagedFeatureTree^ tr, ManagedMat^ bounds_min, ManagedMat^ bounds_max, ManagedMat^ out_indices)
	{
		return cvFindFeaturesBoxed(tr->ToCvFeatureTreePointer(), bounds_min->ToCvMatPointer(), bounds_max->ToCvMatPointer(), out_indices->ToCvMatPointer());
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <param name="d"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <param name="type"></param>
	/// <param name="r"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d, int L, int k, MatFlag type, double r, int64 seed)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d, L, k, (int)type, r, seed), true);
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <param name="d"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d, int L, int k, MatFlag type, double r)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d, L, k, (int)type, r), true);
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <param name="d"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d, int L, int k, MatFlag type)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d, L, k, (int)type), true);
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <param name="d"></param>
	/// <param name="L"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d, int L, int k)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d, L, k), true);
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <param name="d"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d, int L)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d, L), true);
	}

	/// <summary>
	/// Construct a Locality Sensitive Hash (LSH) table, for indexing d-dimensional vectors of
	/// given type. Vectors will be hashed L times with k-dimensional p-stable (p=2) functions.
	/// </summary>
	/// <param name="ops"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateLSH(ManagedLSHOperations^ ops, int d)
	{
		return gcnew ManagedLSH(cvCreateLSH(ops->ToCvLSHOperationsPointer(), d), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <param name="n"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <param name="type"></param>
	/// <param name="r"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n, int L, int k, MatFlag type, double r, int64 seed)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n, L, k, (int)type, r, seed), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <param name="n"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n, int L, int k, MatFlag type, double r)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n, L, k, (int)type, r), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <param name="n"></param>
	/// <param name="L"></param>
	/// <param name="k"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n, int L, int k, MatFlag type)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n, L, k, (int)type), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <param name="n"></param>
	/// <param name="L"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n, int L, int k)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n, L, k), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <param name="n"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n, int L)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n, L), true);
	}

	/// <summary>
	/// Construct in-memory LSH table, with n bins.
	/// </summary>
	/// <param name="d"></param>
	/// <returns></returns>
	static ManagedLSH^ CreateMemoryLSH(int d, int n)
	{
		return gcnew ManagedLSH(cvCreateMemoryLSH(d, n), true);
	}

	/// <summary>
	/// Free the given LSH structure.
	/// </summary>
	static void ReleaseLSH(ManagedLSH^% lsh)
	{
		CvLSH* plsh = lsh->ToCvLSHPointer();
		cvReleaseLSH(&plsh);
		lsh->m_pHandle = plsh;
	}

	/// <summary>
	/// Return the number of vectors in the LSH.
	/// </summary>
	/// <returns></returns>
	static unsigned int HSize(ManagedLSH^ lsh)
	{
		return LSHSize(lsh->ToCvLSHPointer());
	}

	/// <summary>
	/// Add vectors to the LSH structure, optionally returning indices.
	/// </summary>
	/// <param name="lsh"></param>
	/// <param name="data"></param>
	static void LSHAdd(ManagedLSH^ lsh, ManagedMat^ data, ManagedMat^ indices)
	{
		cvLSHAdd(lsh->ToCvLSHPointer(), data->ToCvMatPointer(), indices->ToCvMatPointer());
	}

	/// <summary>
	/// Add vectors to the LSH structure, optionally returning indices.
	/// </summary>
	/// <param name="lsh"></param>
	static void LSHAdd(ManagedLSH^ lsh, ManagedMat^ data)
	{
		cvLSHAdd(lsh->ToCvLSHPointer(), data->ToCvMatPointer());
	}

	/// <summary>
	/// Remove vectors from LSH, as addressed by given indices.
	/// </summary>
	/// <param name="lsh"></param>
	static void LSHRemove(ManagedLSH^ lsh, ManagedMat^ indices)
	{
		cvLSHRemove(lsh->ToCvLSHPointer(), indices->ToCvMatPointer());
	}

	/// <summary>
	/// Query the LSH n times for at most k nearest points; data is n x d,
	/// indices and dist are n x k. At most emax stored points will be accessed.
	/// </summary>
	/// <param name="lsh"></param>
	/// <param name="query_points"></param>
	/// <param name="indices"></param>
	/// <param name="dist"></param>
	/// <param name="k"></param>
	static void LSHQuery(ManagedLSH^ lsh, ManagedMat^ query_points, ManagedMat^ indices, ManagedMat^ dist, int k, int emax)
	{
		cvLSHQuery(lsh->ToCvLSHPointer(), query_points->ToCvMatPointer(), indices->ToCvMatPointer(), dist->ToCvMatPointer(), k, emax);
	}

	/// <summary>
	/// </summary>
	/// <param name="hessianThreshold"></param>
	/// <returns></returns>
	static NAMESPACE::SURFParams SURFParams(double hessianThreshold, int extended)
	{
		return *(NAMESPACE::SURFParams*)&cvSURFParams(hessianThreshold, extended);
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::SURFParams SURFParams(double hessianThreshold)
	{
		return *(NAMESPACE::SURFParams*)&cvSURFParams(hessianThreshold);
	}

	/// <summary>
	/// If useProvidedKeyPts!=0, keypoints are not detected, but descriptors are computed
	/// at the locations provided in keypoints (a CvSeq of CvSURFPoint).
	/// </summary>
	/// <param name="img"></param>
	/// <param name="mask"></param>
	/// <param name="keypoints"></param>
	/// <param name="descriptors"></param>
	/// <param name="storage"></param>
	/// <param name="params"></param>
	static void ExtractSURF(ManagedArr^ img, ManagedArr^ mask, [OutAttribute] ManagedSeq^% keypoints, [OutAttribute] ManagedSeq^% descriptors, ManagedMemStorage^ storage, NAMESPACE::SURFParams params, bool useProvidedKeyPts)
	{
		CvSeq* pkeypoints = NULL;
		CvSeq* pdescriptors = NULL;
		cvExtractSURF(img->ToCvArrPointer(), mask->ToCvArrPointer(), &pkeypoints, &pdescriptors, storage->ToCvMemStoragePointer(), *(CvSURFParams*)&params, (int)useProvidedKeyPts);
		keypoints = gcnew ManagedSeq(pkeypoints);
		descriptors = gcnew ManagedSeq(pdescriptors);
	}

	/// <summary>
	/// If useProvidedKeyPts!=0, keypoints are not detected, but descriptors are computed
	/// at the locations provided in keypoints (a CvSeq of CvSURFPoint).
	/// </summary>
	/// <param name="img"></param>
	/// <param name="mask"></param>
	/// <param name="keypoints"></param>
	/// <param name="descriptors"></param>
	/// <param name="storage"></param>
	static void ExtractSURF(ManagedArr^ img, ManagedArr^ mask, [OutAttribute] ManagedSeq^% keypoints, [OutAttribute] ManagedSeq^% descriptors, ManagedMemStorage^ storage, NAMESPACE::SURFParams params)
	{
		CvSeq* pkeypoints = NULL;
		CvSeq* pdescriptors = NULL;
		cvExtractSURF(img->ToCvArrPointer(), mask->ToCvArrPointer(), &pkeypoints, &pdescriptors, storage->ToCvMemStoragePointer(), *(CvSURFParams*)&params);
		keypoints = gcnew ManagedSeq(pkeypoints);
		descriptors = gcnew ManagedSeq(pdescriptors);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <param name="max_variation"></param>
	/// <param name="min_diversity"></param>
	/// <param name="max_evolution"></param>
	/// <param name="area_threshold"></param>
	/// <param name="min_margin"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation, float min_diversity, int max_evolution, double area_threshold, double min_margin, int edge_blur_size)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation, min_diversity, max_evolution, area_threshold, min_margin, edge_blur_size);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <param name="max_variation"></param>
	/// <param name="min_diversity"></param>
	/// <param name="max_evolution"></param>
	/// <param name="area_threshold"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation, float min_diversity, int max_evolution, double area_threshold, double min_margin)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation, min_diversity, max_evolution, area_threshold, min_margin);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <param name="max_variation"></param>
	/// <param name="min_diversity"></param>
	/// <param name="max_evolution"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation, float min_diversity, int max_evolution, double area_threshold)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation, min_diversity, max_evolution, area_threshold);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <param name="max_variation"></param>
	/// <param name="min_diversity"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation, float min_diversity, int max_evolution)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation, min_diversity, max_evolution);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <param name="max_variation"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation, float min_diversity)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation, min_diversity);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <param name="max_area"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area, float max_variation)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area, max_variation);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <param name="min_area"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area, int max_area)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area, max_area);
	}

	/// <summary>
	/// </summary>
	/// <param name="delta"></param>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta, int min_area)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta, min_area);
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams(int delta)
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams(delta);
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static NAMESPACE::MSERParams MSERParams()
	{
		return *(NAMESPACE::MSERParams*)&cvMSERParams();
	}

	/// <summary>
	/// Extracts the contours of Maximally Stable Extremal Regions
	/// </summary>
	/// <param name="_img"></param>
	/// <param name="_mask"></param>
	/// <param name="contours"></param>
	/// <param name="storage"></param>
	static void ExtractMSER(ManagedArr^ _img, ManagedArr^ _mask, [OutAttribute] ManagedSeq^% contours, ManagedMemStorage^ storage, NAMESPACE::MSERParams params)
	{
		CvSeq* pcontours = NULL;
		cvExtractMSER(_img->ToCvArrPointer(), _mask->ToCvArrPointer(), &pcontours, storage->ToCvMemStoragePointer(), *(CvMSERParams*)&params);
		contours = gcnew ManagedSeq(pcontours);
	}

	/// <summary>
	/// </summary>
	/// <param name="img"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedSeq^ GetStarKeypoints(ManagedArr^ img, ManagedMemStorage^ storage, NAMESPACE::StarDetectorParams params)
	{
		return gcnew ManagedSeq(cvGetStarKeypoints(img->ToCvArrPointer(), storage->ToCvMemStoragePointer(), *(CvStarDetectorParams*)&params));
	}

	/// <summary>
	/// </summary>
	/// <param name="img"></param>
	/// <returns></returns>
	static ManagedSeq^ GetStarKeypoints(ManagedArr^ img, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSeq(cvGetStarKeypoints(img->ToCvArrPointer(), storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// Loads haar classifier cascade from a directory.
	/// It is obsolete: convert your cascade to xml and use cvLoad instead
	/// </summary>
	/// <param name="directory"></param>
	/// <returns></returns>
	static ManagedHaarClassifierCascade^ LoadHaarClassifierCascade(System::String^ directory, NAMESPACE::Point2D32s orig_window_size)
	{
		auto_string pdirectory(directory);
		return gcnew ManagedHaarClassifierCascade(cvLoadHaarClassifierCascade(pdirectory, *(CvSize*)&orig_window_size), true);
	}

	/// <summary>
	/// </summary>
	static void ReleaseHaarClassifierCascade(ManagedHaarClassifierCascade^% cascade)
	{
		CvHaarClassifierCascade* pHaarClassifierCascade = cascade->ToCvHaarClassifierCascadePointer();
		cvReleaseHaarClassifierCascade(&pHaarClassifierCascade);
		cascade->m_pHandle = pHaarClassifierCascade;
	}

	/// <summary>
	/// </summary>
	/// <param name="image"></param>
	/// <param name="cascade"></param>
	/// <param name="storage"></param>
	/// <param name="scale_factor"></param>
	/// <param name="min_neighbors"></param>
	/// <param name="flags"></param>
	/// <returns></returns>
	static ManagedSeq^ HaarDetectObjects(ManagedArr^ image, ManagedHaarClassifierCascade^ cascade, ManagedMemStorage^ storage, double scale_factor, int min_neighbors, HaarFlag flags, NAMESPACE::Size2D32s min_size)
	{
		return gcnew ManagedSeq(cvHaarDetectObjects(image->ToCvArrPointer(), cascade->ToCvHaarClassifierCascadePointer(), storage->ToCvMemStoragePointer(), scale_factor, min_neighbors, (int)flags, *(CvSize*)&min_size));
	}

	/// <summary>
	/// </summary>
	/// <param name="image"></param>
	/// <param name="cascade"></param>
	/// <param name="storage"></param>
	/// <param name="scale_factor"></param>
	/// <param name="min_neighbors"></param>
	/// <returns></returns>
	static ManagedSeq^ HaarDetectObjects(ManagedArr^ image, ManagedHaarClassifierCascade^ cascade, ManagedMemStorage^ storage, double scale_factor, int min_neighbors, HaarFlag flags)
	{
		return gcnew ManagedSeq(cvHaarDetectObjects(image->ToCvArrPointer(), cascade->ToCvHaarClassifierCascadePointer(), storage->ToCvMemStoragePointer(), scale_factor, min_neighbors, (int)flags));
	}

	/// <summary>
	/// </summary>
	/// <param name="image"></param>
	/// <param name="cascade"></param>
	/// <param name="storage"></param>
	/// <param name="scale_factor"></param>
	/// <returns></returns>
	static ManagedSeq^ HaarDetectObjects(ManagedArr^ image, ManagedHaarClassifierCascade^ cascade, ManagedMemStorage^ storage, double scale_factor, int min_neighbors)
	{
		return gcnew ManagedSeq(cvHaarDetectObjects(image->ToCvArrPointer(), cascade->ToCvHaarClassifierCascadePointer(), storage->ToCvMemStoragePointer(), scale_factor, min_neighbors));
	}

	/// <summary>
	/// </summary>
	/// <param name="image"></param>
	/// <param name="cascade"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static ManagedSeq^ HaarDetectObjects(ManagedArr^ image, ManagedHaarClassifierCascade^ cascade, ManagedMemStorage^ storage, double scale_factor)
	{
		return gcnew ManagedSeq(cvHaarDetectObjects(image->ToCvArrPointer(), cascade->ToCvHaarClassifierCascadePointer(), storage->ToCvMemStoragePointer(), scale_factor));
	}

	/// <summary>
	/// </summary>
	/// <param name="image"></param>
	/// <param name="cascade"></param>
	/// <returns></returns>
	static ManagedSeq^ HaarDetectObjects(ManagedArr^ image, ManagedHaarClassifierCascade^ cascade, ManagedMemStorage^ storage)
	{
		return gcnew ManagedSeq(cvHaarDetectObjects(image->ToCvArrPointer(), cascade->ToCvHaarClassifierCascadePointer(), storage->ToCvMemStoragePointer()));
	}

	/// <summary>
	/// sets images for haar classifier cascade
	/// </summary>
	/// <param name="cascade"></param>
	/// <param name="sum"></param>
	/// <param name="sqsum"></param>
	/// <param name="tilted_sum"></param>
	static void SetImagesForHaarClassifierCascade(ManagedHaarClassifierCascade^ cascade, ManagedArr^ sum, ManagedArr^ sqsum, ManagedArr^ tilted_sum, double scale)
	{
		cvSetImagesForHaarClassifierCascade(cascade->ToCvHaarClassifierCascadePointer(), sum->ToCvArrPointer(), sqsum->ToCvArrPointer(), tilted_sum->ToCvArrPointer(), scale);
	}

	/// <summary>
	/// runs the cascade on the specified window
	/// </summary>
	/// <param name="cascade"></param>
	/// <param name="pt"></param>
	/// <returns></returns>
	static int RunHaarClassifierCascade(ManagedHaarClassifierCascade^ cascade, NAMESPACE::Point2D32s pt, bool start_stage)
	{
		return cvRunHaarClassifierCascade(cascade->ToCvHaarClassifierCascadePointer(), *(CvPoint*)&pt, (int)start_stage);
	}

	/// <summary>
	/// runs the cascade on the specified window
	/// </summary>
	/// <param name="cascade"></param>
	/// <returns></returns>
	static int RunHaarClassifierCascade(ManagedHaarClassifierCascade^ cascade, NAMESPACE::Point2D32s pt)
	{
		return cvRunHaarClassifierCascade(cascade->ToCvHaarClassifierCascadePointer(), *(CvPoint*)&pt);
	}

	/// <summary>
	/// Transforms the input image to compensate lens distortion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="camera_matrix"></param>
	static void Undistort2(ManagedArr^ src, ManagedArr^ dst, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs)
	{
		cvUndistort2(src->ToCvArrPointer(), dst->ToCvArrPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer());
	}

	/// <summary>
	/// Computes transformation map from intrinsic camera parameters
	/// that can used by cvRemap
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="mapx"></param>
	static void InitUndistortMap(ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedArr^ mapx, ManagedArr^ mapy)
	{
		cvInitUndistortMap(camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), mapx->ToCvArrPointer(), mapy->ToCvArrPointer());
	}

	/// <summary>
	/// Computes undistortion+rectification map for a head of stereo camera
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="dist_coeffs"></param>
	/// <param name="R"></param>
	/// <param name="new_camera_matrix"></param>
	/// <param name="mapx"></param>
	static void InitUndistortRectifyMap(ManagedMat^ camera_matrix, ManagedMat^ dist_coeffs, ManagedMat^ R, ManagedMat^ new_camera_matrix, ManagedArr^ mapx, ManagedArr^ mapy)
	{
		cvInitUndistortRectifyMap(camera_matrix->ToCvMatPointer(), dist_coeffs->ToCvMatPointer(), R->ToCvMatPointer(),new_camera_matrix->ToCvMatPointer(), mapx->ToCvArrPointer(), mapy->ToCvArrPointer());
	}

	/// <summary>
	/// Computes the original (undistorted) feature coordinates
	/// from the observed (distorted) coordinates
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="dist_coeffs"></param>
	/// <param name="R"></param>
	static void UndistortPoints(ManagedMat^ src, ManagedMat^ dst, ManagedMat^ camera_matrix, ManagedMat^ dist_coeffs, ManagedMat^ R, ManagedMat^ P)
	{
		cvUndistortPoints(src->ToCvMatPointer(), dst->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), dist_coeffs->ToCvMatPointer(), R->ToCvMatPointer(), P->ToCvMatPointer());
	}

	/// <summary>
	/// Computes the original (undistorted) feature coordinates
	/// from the observed (distorted) coordinates
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="dist_coeffs"></param>
	static void UndistortPoints(ManagedMat^ src, ManagedMat^ dst, ManagedMat^ camera_matrix, ManagedMat^ dist_coeffs, ManagedMat^ R)
	{
		cvUndistortPoints(src->ToCvMatPointer(), dst->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), dist_coeffs->ToCvMatPointer(), R->ToCvMatPointer());
	}

	/// <summary>
	/// Computes the original (undistorted) feature coordinates
	/// from the observed (distorted) coordinates
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="camera_matrix"></param>
	static void UndistortPoints(ManagedMat^ src, ManagedMat^ dst, ManagedMat^ camera_matrix, ManagedMat^ dist_coeffs)
	{
		cvUndistortPoints(src->ToCvMatPointer(), dst->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), dist_coeffs->ToCvMatPointer());
	}

	/// <summary>
	/// Converts rotation vector to rotation matrix or vice versa
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static int Rodrigues2(ManagedMat^ src, ManagedMat^ dst, ManagedMat^ jacobian)
	{
		return cvRodrigues2(src->ToCvMatPointer(), dst->ToCvMatPointer(), jacobian->ToCvMatPointer());
	}

	/// <summary>
	/// Converts rotation vector to rotation matrix or vice versa
	/// </summary>
	/// <param name="src"></param>
	/// <returns></returns>
	static int Rodrigues2(ManagedMat^ src, ManagedMat^ dst)
	{
		return cvRodrigues2(src->ToCvMatPointer(), dst->ToCvMatPointer());
	}

	/// <summary>
	/// Finds perspective transformation between the object plane and image (view) plane
	/// </summary>
	/// <param name="src_points"></param>
	/// <param name="dst_points"></param>
	/// <param name="homography"></param>
	/// <param name="method"></param>
	/// <param name="ransacReprojThreshold"></param>
	/// <returns></returns>
	static int FindHomography(ManagedMat^ src_points, ManagedMat^ dst_points, ManagedMat^ homography, FindHomographyMethod method, double ransacReprojThreshold, ManagedMat^ mask)
	{
		return cvFindHomography(src_points->ToCvMatPointer(), dst_points->ToCvMatPointer(), homography->ToCvMatPointer(), (int)method, ransacReprojThreshold, mask->ToCvMatPointer());
	}

	/// <summary>
	/// Finds perspective transformation between the object plane and image (view) plane
	/// </summary>
	/// <param name="src_points"></param>
	/// <param name="dst_points"></param>
	/// <param name="homography"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static int FindHomography(ManagedMat^ src_points, ManagedMat^ dst_points, ManagedMat^ homography, FindHomographyMethod method, double ransacReprojThreshold)
	{
		return cvFindHomography(src_points->ToCvMatPointer(), dst_points->ToCvMatPointer(), homography->ToCvMatPointer(),(int) method, ransacReprojThreshold);
	}

	/// <summary>
	/// Finds perspective transformation between the object plane and image (view) plane
	/// </summary>
	/// <param name="src_points"></param>
	/// <param name="dst_points"></param>
	/// <param name="homography"></param>
	/// <returns></returns>
	static int FindHomography(ManagedMat^ src_points, ManagedMat^ dst_points, ManagedMat^ homography, FindHomographyMethod method)
	{
		return cvFindHomography(src_points->ToCvMatPointer(), dst_points->ToCvMatPointer(), homography->ToCvMatPointer(), (int)method);
	}

	/// <summary>
	/// Finds perspective transformation between the object plane and image (view) plane
	/// </summary>
	/// <param name="src_points"></param>
	/// <param name="dst_points"></param>
	/// <returns></returns>
	static int FindHomography(ManagedMat^ src_points, ManagedMat^ dst_points, ManagedMat^ homography)
	{
		return cvFindHomography(src_points->ToCvMatPointer(), dst_points->ToCvMatPointer(), homography->ToCvMatPointer());
	}

	/// <summary>
	/// Computes RQ decomposition for 3x3 matrices
	/// </summary>
	/// <param name="matrixM"></param>
	/// <param name="matrixR"></param>
	/// <param name="matrixQ"></param>
	/// <param name="matrixQx"></param>
	/// <param name="matrixQy"></param>
	/// <param name="matrixQz"></param>
	static void RQDecomp3x3(ManagedMat^ matrixM, ManagedMat^ matrixR, ManagedMat^ matrixQ, ManagedMat^ matrixQx, ManagedMat^ matrixQy, ManagedMat^ matrixQz, [OutAttribute] NAMESPACE::Point3D64f% eulerAngles)
	{
		pin_ptr<NAMESPACE::Point3D64f> peulerAngles = &eulerAngles;
		cvRQDecomp3x3(matrixM->ToCvMatPointer(), matrixR->ToCvMatPointer(), matrixQ->ToCvMatPointer(), matrixQx->ToCvMatPointer(), matrixQy->ToCvMatPointer(), matrixQz->ToCvMatPointer(), (CvPoint3D64f*)peulerAngles);
	}

	/// <summary>
	/// Computes RQ decomposition for 3x3 matrices
	/// </summary>
	/// <param name="matrixM"></param>
	/// <param name="matrixR"></param>
	/// <param name="matrixQ"></param>
	/// <param name="matrixQx"></param>
	/// <param name="matrixQy"></param>
	static void RQDecomp3x3(ManagedMat^ matrixM, ManagedMat^ matrixR, ManagedMat^ matrixQ, ManagedMat^ matrixQx, ManagedMat^ matrixQy, ManagedMat^ matrixQz)
	{
		cvRQDecomp3x3(matrixM->ToCvMatPointer(), matrixR->ToCvMatPointer(), matrixQ->ToCvMatPointer(), matrixQx->ToCvMatPointer(), matrixQy->ToCvMatPointer(), matrixQz->ToCvMatPointer());
	}

	/// <summary>
	/// Computes RQ decomposition for 3x3 matrices
	/// </summary>
	/// <param name="matrixM"></param>
	/// <param name="matrixR"></param>
	/// <param name="matrixQ"></param>
	/// <param name="matrixQx"></param>
	static void RQDecomp3x3(ManagedMat^ matrixM, ManagedMat^ matrixR, ManagedMat^ matrixQ, ManagedMat^ matrixQx, ManagedMat^ matrixQy)
	{
		cvRQDecomp3x3(matrixM->ToCvMatPointer(), matrixR->ToCvMatPointer(), matrixQ->ToCvMatPointer(), matrixQx->ToCvMatPointer(), matrixQy->ToCvMatPointer());
	}

	/// <summary>
	/// Computes RQ decomposition for 3x3 matrices
	/// </summary>
	/// <param name="matrixM"></param>
	/// <param name="matrixR"></param>
	/// <param name="matrixQ"></param>
	static void RQDecomp3x3(ManagedMat^ matrixM, ManagedMat^ matrixR, ManagedMat^ matrixQ, ManagedMat^ matrixQx)
	{
		cvRQDecomp3x3(matrixM->ToCvMatPointer(), matrixR->ToCvMatPointer(), matrixQ->ToCvMatPointer(), matrixQx->ToCvMatPointer());
	}

	/// <summary>
	/// Computes RQ decomposition for 3x3 matrices
	/// </summary>
	/// <param name="matrixM"></param>
	/// <param name="matrixR"></param>
	static void RQDecomp3x3(ManagedMat^ matrixM, ManagedMat^ matrixR, ManagedMat^ matrixQ)
	{
		cvRQDecomp3x3(matrixM->ToCvMatPointer(), matrixR->ToCvMatPointer(), matrixQ->ToCvMatPointer());
	}

	/// <summary>
	/// Computes projection matrix decomposition
	/// </summary>
	/// <param name="projMatr"></param>
	/// <param name="calibMatr"></param>
	/// <param name="rotMatr"></param>
	/// <param name="posVect"></param>
	/// <param name="rotMatrX"></param>
	/// <param name="rotMatrY"></param>
	/// <param name="rotMatrZ"></param>
	static void DecomposeProjectionMatrix(ManagedMat^ projMatr, ManagedMat^ calibMatr, ManagedMat^ rotMatr, ManagedMat^ posVect, ManagedMat^ rotMatrX, ManagedMat^ rotMatrY, ManagedMat^ rotMatrZ, [OutAttribute] NAMESPACE::Point3D64f% eulerAngles)
	{
		pin_ptr<NAMESPACE::Point3D64f> peulerAngles = &eulerAngles;
		cvDecomposeProjectionMatrix(projMatr->ToCvMatPointer(), calibMatr->ToCvMatPointer(), rotMatr->ToCvMatPointer(), posVect->ToCvMatPointer(), rotMatrX->ToCvMatPointer(), rotMatrY->ToCvMatPointer(), rotMatrZ->ToCvMatPointer(), (CvPoint3D64f*)peulerAngles);
	}

	/// <summary>
	/// Computes projection matrix decomposition
	/// </summary>
	/// <param name="projMatr"></param>
	/// <param name="calibMatr"></param>
	/// <param name="rotMatr"></param>
	/// <param name="posVect"></param>
	/// <param name="rotMatrX"></param>
	/// <param name="rotMatrY"></param>
	static void DecomposeProjectionMatrix(ManagedMat^ projMatr, ManagedMat^ calibMatr, ManagedMat^ rotMatr, ManagedMat^ posVect, ManagedMat^ rotMatrX, ManagedMat^ rotMatrY, ManagedMat^ rotMatrZ)
	{
		cvDecomposeProjectionMatrix(projMatr->ToCvMatPointer(), calibMatr->ToCvMatPointer(), rotMatr->ToCvMatPointer(), posVect->ToCvMatPointer(), rotMatrX->ToCvMatPointer(), rotMatrY->ToCvMatPointer(), rotMatrZ->ToCvMatPointer());
	}

	/// <summary>
	/// Computes projection matrix decomposition
	/// </summary>
	/// <param name="projMatr"></param>
	/// <param name="calibMatr"></param>
	/// <param name="rotMatr"></param>
	/// <param name="posVect"></param>
	/// <param name="rotMatrX"></param>
	static void DecomposeProjectionMatrix(ManagedMat^ projMatr, ManagedMat^ calibMatr, ManagedMat^ rotMatr, ManagedMat^ posVect, ManagedMat^ rotMatrX, ManagedMat^ rotMatrY)
	{
		cvDecomposeProjectionMatrix(projMatr->ToCvMatPointer(), calibMatr->ToCvMatPointer(), rotMatr->ToCvMatPointer(), posVect->ToCvMatPointer(), rotMatrX->ToCvMatPointer(), rotMatrY->ToCvMatPointer());
	}

	/// <summary>
	/// Computes projection matrix decomposition
	/// </summary>
	/// <param name="projMatr"></param>
	/// <param name="calibMatr"></param>
	/// <param name="rotMatr"></param>
	/// <param name="posVect"></param>
	static void DecomposeProjectionMatrix(ManagedMat^ projMatr, ManagedMat^ calibMatr, ManagedMat^ rotMatr, ManagedMat^ posVect, ManagedMat^ rotMatrX)
	{
		cvDecomposeProjectionMatrix(projMatr->ToCvMatPointer(), calibMatr->ToCvMatPointer(), rotMatr->ToCvMatPointer(), posVect->ToCvMatPointer(), rotMatrX->ToCvMatPointer());
	}

	/// <summary>
	/// Computes projection matrix decomposition
	/// </summary>
	/// <param name="projMatr"></param>
	/// <param name="calibMatr"></param>
	/// <param name="rotMatr"></param>
	static void DecomposeProjectionMatrix(ManagedMat^ projMatr, ManagedMat^ calibMatr, ManagedMat^ rotMatr, ManagedMat^ posVect)
	{
		cvDecomposeProjectionMatrix(projMatr->ToCvMatPointer(), calibMatr->ToCvMatPointer(), rotMatr->ToCvMatPointer(), posVect->ToCvMatPointer());
	}

	/// <summary>
	/// Computes d(AB)/dA and d(AB)/dB
	/// </summary>
	/// <param name="A"></param>
	/// <param name="B"></param>
	/// <param name="dABdA"></param>
	static void CalcMatMulDeriv(ManagedMat^ A, ManagedMat^ B, ManagedMat^ dABdA, ManagedMat^ dABdB)
	{
		cvCalcMatMulDeriv(A->ToCvMatPointer(), B->ToCvMatPointer(), dABdA->ToCvMatPointer(), dABdB->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	/// <param name="dr3dr2"></param>
	/// <param name="dr3dt2"></param>
	/// <param name="dt3dr1"></param>
	/// <param name="dt3dt1"></param>
	/// <param name="dt3dr2"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2, ManagedMat^ dr3dt2, ManagedMat^ dt3dr1, ManagedMat^ dt3dt1, ManagedMat^ dt3dr2, ManagedMat^ dt3dt2)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer(), dr3dt2->ToCvMatPointer(), dt3dr1->ToCvMatPointer(), dt3dt1->ToCvMatPointer(), dt3dr2->ToCvMatPointer(), dt3dt2->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	/// <param name="dr3dr2"></param>
	/// <param name="dr3dt2"></param>
	/// <param name="dt3dr1"></param>
	/// <param name="dt3dt1"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2, ManagedMat^ dr3dt2, ManagedMat^ dt3dr1, ManagedMat^ dt3dt1, ManagedMat^ dt3dr2)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer(), dr3dt2->ToCvMatPointer(), dt3dr1->ToCvMatPointer(), dt3dt1->ToCvMatPointer(), dt3dr2->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	/// <param name="dr3dr2"></param>
	/// <param name="dr3dt2"></param>
	/// <param name="dt3dr1"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2, ManagedMat^ dr3dt2, ManagedMat^ dt3dr1, ManagedMat^ dt3dt1)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer(), dr3dt2->ToCvMatPointer(), dt3dr1->ToCvMatPointer(), dt3dt1->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	/// <param name="dr3dr2"></param>
	/// <param name="dr3dt2"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2, ManagedMat^ dr3dt2, ManagedMat^ dt3dr1)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer(), dr3dt2->ToCvMatPointer(), dt3dr1->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	/// <param name="dr3dr2"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2, ManagedMat^ dr3dt2)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer(), dr3dt2->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	/// <param name="dr3dt1"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1, ManagedMat^ dr3dr2)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer(), dr3dr2->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	/// <param name="dr3dr1"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1, ManagedMat^ dr3dt1)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer(), dr3dt1->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	/// <param name="_tvec3"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3, ManagedMat^ dr3dr1)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer(), dr3dr1->ToCvMatPointer());
	}

	/// <summary>
	/// Computes r3 = rodrigues(rodrigues(r2)*rodrigues(r1)),
	/// t3 = rodrigues(r2)*t1 + t2 and the respective derivatives
	/// </summary>
	/// <param name="_rvec1"></param>
	/// <param name="_tvec1"></param>
	/// <param name="_rvec2"></param>
	/// <param name="_tvec2"></param>
	/// <param name="_rvec3"></param>
	static void ComposeRT(ManagedMat^ _rvec1, ManagedMat^ _tvec1, ManagedMat^ _rvec2, ManagedMat^ _tvec2, ManagedMat^ _rvec3, ManagedMat^ _tvec3)
	{
		cvComposeRT(_rvec1->ToCvMatPointer(), _tvec1->ToCvMatPointer(), _rvec2->ToCvMatPointer(), _tvec2->ToCvMatPointer(), _rvec3->ToCvMatPointer(), _tvec3->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	/// <param name="dpdrot"></param>
	/// <param name="dpdt"></param>
	/// <param name="dpdf"></param>
	/// <param name="dpdc"></param>
	/// <param name="dpddist"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot, ManagedMat^ dpdt, ManagedMat^ dpdf, ManagedMat^ dpdc, ManagedMat^ dpddist, double aspect_ratio)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer(), dpdt->ToCvMatPointer(), dpdf->ToCvMatPointer(), dpdc->ToCvMatPointer(), dpddist->ToCvMatPointer(), aspect_ratio);
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	/// <param name="dpdrot"></param>
	/// <param name="dpdt"></param>
	/// <param name="dpdf"></param>
	/// <param name="dpdc"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot, ManagedMat^ dpdt, ManagedMat^ dpdf, ManagedMat^ dpdc, ManagedMat^ dpddist)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer(), dpdt->ToCvMatPointer(), dpdf->ToCvMatPointer(), dpdc->ToCvMatPointer(), dpddist->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	/// <param name="dpdrot"></param>
	/// <param name="dpdt"></param>
	/// <param name="dpdf"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot, ManagedMat^ dpdt, ManagedMat^ dpdf, ManagedMat^ dpdc)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer(), dpdt->ToCvMatPointer(), dpdf->ToCvMatPointer(), dpdc->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	/// <param name="dpdrot"></param>
	/// <param name="dpdt"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot, ManagedMat^ dpdt, ManagedMat^ dpdf)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer(), dpdt->ToCvMatPointer(), dpdf->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	/// <param name="dpdrot"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot, ManagedMat^ dpdt)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer(), dpdt->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="image_points"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points, ManagedMat^ dpdrot)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer(), dpdrot->ToCvMatPointer());
	}

	/// <summary>
	/// Projects object points to the view plane using
	/// the specified extrinsic and intrinsic camera parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	static void ProjectPoints2(ManagedMat^ object_points, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ image_points)
	{
		cvProjectPoints2(object_points->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), image_points->ToCvMatPointer());
	}

	/// <summary>
	/// Finds extrinsic camera parameters from
	/// a few known corresponding point pairs and intrinsic parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="rotation_vector"></param>
	/// <param name="translation_vector"></param>
	static void FindExtrinsicCameraParams2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ rotation_vector, ManagedMat^ translation_vector, int use_extrinsic_guess)
	{
		cvFindExtrinsicCameraParams2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer(), use_extrinsic_guess);
	}

	/// <summary>
	/// Finds extrinsic camera parameters from
	/// a few known corresponding point pairs and intrinsic parameters
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="rotation_vector"></param>
	static void FindExtrinsicCameraParams2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ rotation_vector, ManagedMat^ translation_vector)
	{
		cvFindExtrinsicCameraParams2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), rotation_vector->ToCvMatPointer(), translation_vector->ToCvMatPointer());
	}

	/// <summary>
	/// Computes initial estimate of the intrinsic camera parameters
	/// in case of planar calibration target (e.g. chessboard)
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="npoints"></param>
	/// <param name="image_size"></param>
	/// <param name="camera_matrix"></param>
	static void InitIntrinsicParams2D(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ npoints, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix, double aspect_ratio)
	{
		cvInitIntrinsicParams2D(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), npoints->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer(), aspect_ratio);
	}

	/// <summary>
	/// Computes initial estimate of the intrinsic camera parameters
	/// in case of planar calibration target (e.g. chessboard)
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="npoints"></param>
	/// <param name="image_size"></param>
	static void InitIntrinsicParams2D(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ npoints, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix)
	{
		cvInitIntrinsicParams2D(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), npoints->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer());
	}

	/// <summary>
	/// Detects corners on a chessboard calibration pattern
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pattern_size"></param>
	/// <param name="corners"></param>
	/// <param name="corner_count"></param>
	/// <returns></returns>
	static int FindChessboardCorners(ManagedArr^ image, NAMESPACE::Size2D32s pattern_size, array<NAMESPACE::Point2D32f>^ corners, [OutAttribute] int% corner_count, FindChessboardCornerFlag flags)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		return cvFindChessboardCorners(image->ToCvArrPointer(), *(CvSize*)&pattern_size, (CvPoint2D32f*)pcorners, pcorner_count, (int)flags);
	}

	/// <summary>
	/// Detects corners on a chessboard calibration pattern
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pattern_size"></param>
	/// <param name="corners"></param>
	/// <returns></returns>
	static int FindChessboardCorners(ManagedArr^ image, NAMESPACE::Size2D32s pattern_size, array<NAMESPACE::Point2D32f>^ corners, [OutAttribute] int% corner_count)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		pin_ptr<int> pcorner_count = &corner_count;
		return cvFindChessboardCorners(image->ToCvArrPointer(), *(CvSize*)&pattern_size, (CvPoint2D32f*)pcorners, pcorner_count);
	}

	/// <summary>
	/// Detects corners on a chessboard calibration pattern
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pattern_size"></param>
	/// <returns></returns>
	static int FindChessboardCorners(ManagedArr^ image, NAMESPACE::Size2D32s pattern_size, array<NAMESPACE::Point2D32f>^ corners)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		return cvFindChessboardCorners(image->ToCvArrPointer(), *(CvSize*)&pattern_size, (CvPoint2D32f*)pcorners);
	}

	/// <summary>
	/// Draws individual chessboard corners or the whole chessboard detected
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pattern_size"></param>
	/// <param name="corners"></param>
	/// <param name="count"></param>
	static void DrawChessboardCorners(ManagedArr^ image, NAMESPACE::Size2D32s pattern_size, array<NAMESPACE::Point2D32f>^ corners, int count, int pattern_was_found)
	{
		pin_ptr<NAMESPACE::Point2D32f> pcorners = &corners[0];
		cvDrawChessboardCorners(image->ToCvArrPointer(), *(CvSize*)&pattern_size, (CvPoint2D32f*)pcorners, count, pattern_was_found);
	}

	/// <summary>
	/// Finds intrinsic and extrinsic camera parameters
	/// from a few views of known calibration pattern
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="point_counts"></param>
	/// <param name="image_size"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="rotation_vectors"></param>
	/// <param name="translation_vectors"></param>
	static void CalibrateCamera2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ point_counts, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ rotation_vectors, ManagedMat^ translation_vectors, CalibrateCamraFlag flags)
	{
		cvCalibrateCamera2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), point_counts->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), rotation_vectors->ToCvMatPointer(), translation_vectors->ToCvMatPointer(), (int)flags);
	}

	/// <summary>
	/// Finds intrinsic and extrinsic camera parameters
	/// from a few views of known calibration pattern
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="point_counts"></param>
	/// <param name="image_size"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	/// <param name="rotation_vectors"></param>
	static void CalibrateCamera2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ point_counts, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ rotation_vectors, ManagedMat^ translation_vectors)
	{
		cvCalibrateCamera2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), point_counts->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), rotation_vectors->ToCvMatPointer(), translation_vectors->ToCvMatPointer());
	}

	/// <summary>
	/// Finds intrinsic and extrinsic camera parameters
	/// from a few views of known calibration pattern
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="point_counts"></param>
	/// <param name="image_size"></param>
	/// <param name="camera_matrix"></param>
	/// <param name="distortion_coeffs"></param>
	static void CalibrateCamera2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ point_counts, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs, ManagedMat^ rotation_vectors)
	{
		cvCalibrateCamera2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), point_counts->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer(), rotation_vectors->ToCvMatPointer());
	}

	/// <summary>
	/// Finds intrinsic and extrinsic camera parameters
	/// from a few views of known calibration pattern
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points"></param>
	/// <param name="point_counts"></param>
	/// <param name="image_size"></param>
	/// <param name="camera_matrix"></param>
	static void CalibrateCamera2(ManagedMat^ object_points, ManagedMat^ image_points, ManagedMat^ point_counts, NAMESPACE::Size2D32s image_size, ManagedMat^ camera_matrix, ManagedMat^ distortion_coeffs)
	{
		cvCalibrateCamera2(object_points->ToCvMatPointer(), image_points->ToCvMatPointer(), point_counts->ToCvMatPointer(), *(CvSize*)&image_size, camera_matrix->ToCvMatPointer(), distortion_coeffs->ToCvMatPointer());
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	/// <param name="aperture_height"></param>
	/// <param name="fovx"></param>
	/// <param name="fovy"></param>
	/// <param name="focal_length"></param>
	/// <param name="principal_point"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height, [OutAttribute] double% fovx, [OutAttribute] double% fovy, [OutAttribute] double% focal_length, [OutAttribute] NAMESPACE::Point2D64f% principal_point, [OutAttribute] double% pixel_aspect_ratio)
	{
		pin_ptr<double> pfovx = &fovx;
		pin_ptr<double> pfovy = &fovy;
		pin_ptr<double> pfocal_length = &focal_length;
		pin_ptr<NAMESPACE::Point2D64f> pprincipal_point = &principal_point;
		pin_ptr<double> ppixel_aspect_ratio = &pixel_aspect_ratio;
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height, pfovx, pfovy, pfocal_length, (CvPoint2D64f*)pprincipal_point, ppixel_aspect_ratio);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	/// <param name="aperture_height"></param>
	/// <param name="fovx"></param>
	/// <param name="fovy"></param>
	/// <param name="focal_length"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height, [OutAttribute] double% fovx, [OutAttribute] double% fovy, [OutAttribute] double% focal_length, [OutAttribute] NAMESPACE::Point2D64f% principal_point)
	{
		pin_ptr<double> pfovx = &fovx;
		pin_ptr<double> pfovy = &fovy;
		pin_ptr<double> pfocal_length = &focal_length;
		pin_ptr<NAMESPACE::Point2D64f> pprincipal_point = &principal_point;
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height, pfovx, pfovy, pfocal_length, (CvPoint2D64f*)pprincipal_point);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	/// <param name="aperture_height"></param>
	/// <param name="fovx"></param>
	/// <param name="fovy"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height, [OutAttribute] double% fovx, [OutAttribute] double% fovy, [OutAttribute] double% focal_length)
	{
		pin_ptr<double> pfovx = &fovx;
		pin_ptr<double> pfovy = &fovy;
		pin_ptr<double> pfocal_length = &focal_length;
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height, pfovx, pfovy, pfocal_length);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	/// <param name="aperture_height"></param>
	/// <param name="fovx"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height, [OutAttribute] double% fovx, [OutAttribute] double% fovy)
	{
		pin_ptr<double> pfovx = &fovx;
		pin_ptr<double> pfovy = &fovy;
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height, pfovx, pfovy);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	/// <param name="aperture_height"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height, [OutAttribute] double% fovx)
	{
		pin_ptr<double> pfovx = &fovx;
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height, pfovx);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	/// <param name="aperture_width"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width, double aperture_height)
	{
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width, aperture_height);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	/// <param name="image_size"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size, double aperture_width)
	{
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size, aperture_width);
	}

	/// <summary>
	/// Computes various useful characteristics of the camera from the data computed by
	/// cvCalibrateCamera2
	/// </summary>
	/// <param name="camera_matrix"></param>
	static void CalibrationMatrixValues(ManagedMat^ camera_matrix, NAMESPACE::Size2D32s image_size)
	{
		cvCalibrationMatrixValues(camera_matrix->ToCvMatPointer(), *(CvSize*)&image_size);
	}

	/// <summary>
	/// Computes the transformation from one camera coordinate system to another one
	/// from a few correspondent views of the same calibration target. Optionally, calibrates
	/// both cameras
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points1"></param>
	/// <param name="image_points2"></param>
	/// <param name="npoints"></param>
	/// <param name="camera_matrix1"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="E"></param>
	/// <param name="F"></param>
	/// <param name="term_crit"></param>
	static void StereoCalibrate(ManagedMat^ object_points, ManagedMat^ image_points1, ManagedMat^ image_points2, ManagedMat^ npoints, ManagedMat^ camera_matrix1, ManagedMat^ dist_coeffs1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ E, ManagedMat^ F, NAMESPACE::TermCriteria term_crit, int flags)
	{
		cvStereoCalibrate(object_points->ToCvMatPointer(), image_points1->ToCvMatPointer(), image_points2->ToCvMatPointer(), npoints->ToCvMatPointer(), camera_matrix1->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), E->ToCvMatPointer(), F->ToCvMatPointer(), *(CvTermCriteria*)&term_crit, flags);
	}

	/// <summary>
	/// Computes the transformation from one camera coordinate system to another one
	/// from a few correspondent views of the same calibration target. Optionally, calibrates
	/// both cameras
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points1"></param>
	/// <param name="image_points2"></param>
	/// <param name="npoints"></param>
	/// <param name="camera_matrix1"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="E"></param>
	/// <param name="F"></param>
	static void StereoCalibrate(ManagedMat^ object_points, ManagedMat^ image_points1, ManagedMat^ image_points2, ManagedMat^ npoints, ManagedMat^ camera_matrix1, ManagedMat^ dist_coeffs1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ E, ManagedMat^ F, NAMESPACE::TermCriteria term_crit)
	{
		cvStereoCalibrate(object_points->ToCvMatPointer(), image_points1->ToCvMatPointer(), image_points2->ToCvMatPointer(), npoints->ToCvMatPointer(), camera_matrix1->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), E->ToCvMatPointer(), F->ToCvMatPointer(), *(CvTermCriteria*)&term_crit);
	}

	/// <summary>
	/// Computes the transformation from one camera coordinate system to another one
	/// from a few correspondent views of the same calibration target. Optionally, calibrates
	/// both cameras
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points1"></param>
	/// <param name="image_points2"></param>
	/// <param name="npoints"></param>
	/// <param name="camera_matrix1"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="E"></param>
	static void StereoCalibrate(ManagedMat^ object_points, ManagedMat^ image_points1, ManagedMat^ image_points2, ManagedMat^ npoints, ManagedMat^ camera_matrix1, ManagedMat^ dist_coeffs1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ E, ManagedMat^ F)
	{
		cvStereoCalibrate(object_points->ToCvMatPointer(), image_points1->ToCvMatPointer(), image_points2->ToCvMatPointer(), npoints->ToCvMatPointer(), camera_matrix1->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), E->ToCvMatPointer(), F->ToCvMatPointer());
	}

	/// <summary>
	/// Computes the transformation from one camera coordinate system to another one
	/// from a few correspondent views of the same calibration target. Optionally, calibrates
	/// both cameras
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points1"></param>
	/// <param name="image_points2"></param>
	/// <param name="npoints"></param>
	/// <param name="camera_matrix1"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	static void StereoCalibrate(ManagedMat^ object_points, ManagedMat^ image_points1, ManagedMat^ image_points2, ManagedMat^ npoints, ManagedMat^ camera_matrix1, ManagedMat^ dist_coeffs1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ E)
	{
		cvStereoCalibrate(object_points->ToCvMatPointer(), image_points1->ToCvMatPointer(), image_points2->ToCvMatPointer(), npoints->ToCvMatPointer(), camera_matrix1->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), E->ToCvMatPointer());
	}

	/// <summary>
	/// Computes the transformation from one camera coordinate system to another one
	/// from a few correspondent views of the same calibration target. Optionally, calibrates
	/// both cameras
	/// </summary>
	/// <param name="object_points"></param>
	/// <param name="image_points1"></param>
	/// <param name="image_points2"></param>
	/// <param name="npoints"></param>
	/// <param name="camera_matrix1"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	static void StereoCalibrate(ManagedMat^ object_points, ManagedMat^ image_points1, ManagedMat^ image_points2, ManagedMat^ npoints, ManagedMat^ camera_matrix1, ManagedMat^ dist_coeffs1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T)
	{
		cvStereoCalibrate(object_points->ToCvMatPointer(), image_points1->ToCvMatPointer(), image_points2->ToCvMatPointer(), npoints->ToCvMatPointer(), camera_matrix1->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer());
	}

	/// <summary>
	/// Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
	/// views parallel (=> to make all the epipolar lines horizontal or vertical)
	/// </summary>
	/// <param name="camera_matrix1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="R1"></param>
	/// <param name="R2"></param>
	/// <param name="P1"></param>
	/// <param name="P2"></param>
	/// <param name="Q"></param>
	static void StereoRectify(ManagedMat^ camera_matrix1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs1, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ R1, ManagedMat^ R2, ManagedMat^ P1, ManagedMat^ P2, ManagedMat^ Q, int flags)
	{
		cvStereoRectify(camera_matrix1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), R1->ToCvMatPointer(), R2->ToCvMatPointer(), P1->ToCvMatPointer(), P2->ToCvMatPointer(), Q->ToCvMatPointer(), flags);
	}

	/// <summary>
	/// Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
	/// views parallel (=> to make all the epipolar lines horizontal or vertical)
	/// </summary>
	/// <param name="camera_matrix1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="R1"></param>
	/// <param name="R2"></param>
	/// <param name="P1"></param>
	/// <param name="P2"></param>
	static void StereoRectify(ManagedMat^ camera_matrix1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs1, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ R1, ManagedMat^ R2, ManagedMat^ P1, ManagedMat^ P2, ManagedMat^ Q)
	{
		cvStereoRectify(camera_matrix1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), R1->ToCvMatPointer(), R2->ToCvMatPointer(), P1->ToCvMatPointer(), P2->ToCvMatPointer(), Q->ToCvMatPointer());
	}

	/// <summary>
	/// Computes 3D rotations (+ optional shift) for each camera coordinate system to make both
	/// views parallel (=> to make all the epipolar lines horizontal or vertical)
	/// </summary>
	/// <param name="camera_matrix1"></param>
	/// <param name="camera_matrix2"></param>
	/// <param name="dist_coeffs1"></param>
	/// <param name="dist_coeffs2"></param>
	/// <param name="image_size"></param>
	/// <param name="R"></param>
	/// <param name="T"></param>
	/// <param name="R1"></param>
	/// <param name="R2"></param>
	/// <param name="P1"></param>
	static void StereoRectify(ManagedMat^ camera_matrix1, ManagedMat^ camera_matrix2, ManagedMat^ dist_coeffs1, ManagedMat^ dist_coeffs2, NAMESPACE::Size2D32s image_size, ManagedMat^ R, ManagedMat^ T, ManagedMat^ R1, ManagedMat^ R2, ManagedMat^ P1, ManagedMat^ P2)
	{
		cvStereoRectify(camera_matrix1->ToCvMatPointer(), camera_matrix2->ToCvMatPointer(), dist_coeffs1->ToCvMatPointer(), dist_coeffs2->ToCvMatPointer(), *(CvSize*)&image_size, R->ToCvMatPointer(), T->ToCvMatPointer(), R1->ToCvMatPointer(), R2->ToCvMatPointer(), P1->ToCvMatPointer(), P2->ToCvMatPointer());
	}

	/// <summary>
	/// Computes rectification transformations for uncalibrated pair of images using a set
	/// of point correspondences
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="F"></param>
	/// <param name="img_size"></param>
	/// <param name="H1"></param>
	/// <param name="H2"></param>
	/// <returns></returns>
	static int StereoRectifyUncalibrated(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ F, NAMESPACE::Size2D32s img_size, ManagedMat^ H1, ManagedMat^ H2, double threshold)
	{
		return cvStereoRectifyUncalibrated(points1->ToCvMatPointer(), points2->ToCvMatPointer(), F->ToCvMatPointer(), *(CvSize*)&img_size, H1->ToCvMatPointer(), H2->ToCvMatPointer(), threshold);
	}

	/// <summary>
	/// Computes rectification transformations for uncalibrated pair of images using a set
	/// of point correspondences
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="F"></param>
	/// <param name="img_size"></param>
	/// <param name="H1"></param>
	/// <returns></returns>
	static int StereoRectifyUncalibrated(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ F, NAMESPACE::Size2D32s img_size, ManagedMat^ H1, ManagedMat^ H2)
	{
		return cvStereoRectifyUncalibrated(points1->ToCvMatPointer(), points2->ToCvMatPointer(), F->ToCvMatPointer(), *(CvSize*)&img_size, H1->ToCvMatPointer(), H2->ToCvMatPointer());
	}

	/// <summary>
	/// Allocates and initializes CvPOSITObject structure before doing cvPOSIT
	/// </summary>
	/// <param name="points"></param>
	/// <returns></returns>
	static ManagedPOSITObject^ CreatePOSITObject(array<NAMESPACE::Point3D32f>^ points, int point_count)
	{
		pin_ptr<NAMESPACE::Point3D32f> ppoints = &points[0];
		return gcnew ManagedPOSITObject(cvCreatePOSITObject((CvPoint3D32f*)ppoints, point_count), true);
	}

	/// <summary>
	/// Runs POSIT (POSe from ITeration) algorithm for determining 3d position of
	/// an object given its model and projection in a weak-perspective case
	/// </summary>
	/// <param name="posit_object"></param>
	/// <param name="image_points"></param>
	/// <param name="focal_length"></param>
	/// <param name="criteria"></param>
	/// <param name="rotation_matrix"></param>
	static void POSIT(ManagedPOSITObject^ posit_object, array<NAMESPACE::Point2D32f>^ image_points, double focal_length, NAMESPACE::TermCriteria criteria, array<float>^ rotation_matrix, array<float>^ translation_vector)
	{
		pin_ptr<NAMESPACE::Point2D32f> pimage_points = &image_points[0];
		pin_ptr<float> protation_matrix = &rotation_matrix[0];
		pin_ptr<float> ptranslation_vector = &translation_vector[0];
		cvPOSIT(posit_object->ToCvPOSITObjectPointer(), (CvPoint2D32f*)pimage_points, focal_length, *(CvTermCriteria*)&criteria, (CvMatr32f)protation_matrix, (CvVect32f)ptranslation_vector);
	}

	/// <summary>
	/// Releases CvPOSITObject structure
	/// </summary>
	static void ReleasePOSITObject(ManagedPOSITObject^% posit_object)
	{
		CvPOSITObject* pPOSITObject = posit_object->ToCvPOSITObjectPointer();
		cvReleasePOSITObject(&pPOSITObject);
		posit_object->m_pHandle = pPOSITObject;
	}

	/// <summary>
	/// updates the number of RANSAC iterations
	/// </summary>
	/// <param name="p"></param>
	/// <param name="err_prob"></param>
	/// <param name="model_points"></param>
	/// <returns></returns>
	static int RANSACUpdateNumIters(double p, double err_prob, int model_points, int max_iters)
	{
		return cvRANSACUpdateNumIters(p, err_prob, model_points, max_iters);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	static void ConvertPointsHomogeneous(ManagedMat^ src, ManagedMat^ dst)
	{
		cvConvertPointsHomogeneous(src->ToCvMatPointer(), dst->ToCvMatPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="fundamental_matrix"></param>
	/// <param name="method"></param>
	/// <param name="param1"></param>
	/// <param name="param2"></param>
	/// <returns></returns>
	static int FindFundamentalMat(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ fundamental_matrix, FindFundamentalMatMethod method, double param1, double param2, ManagedMat^ status)
	{
		return cvFindFundamentalMat(points1->ToCvMatPointer(), points2->ToCvMatPointer(), fundamental_matrix->ToCvMatPointer(), (int)method, param1, param2, status->ToCvMatPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="fundamental_matrix"></param>
	/// <param name="method"></param>
	/// <param name="param1"></param>
	/// <returns></returns>
	static int FindFundamentalMat(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ fundamental_matrix, FindFundamentalMatMethod method, double param1, double param2)
	{
		return cvFindFundamentalMat(points1->ToCvMatPointer(), points2->ToCvMatPointer(), fundamental_matrix->ToCvMatPointer(), (int)method, param1, param2);
	}

	/// <summary>
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="fundamental_matrix"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static int FindFundamentalMat(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ fundamental_matrix, FindFundamentalMatMethod method, double param1)
	{
		return cvFindFundamentalMat(points1->ToCvMatPointer(), points2->ToCvMatPointer(), fundamental_matrix->ToCvMatPointer(), (int)method, param1);
	}

	/// <summary>
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="fundamental_matrix"></param>
	/// <returns></returns>
	static int FindFundamentalMat(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ fundamental_matrix, FindFundamentalMatMethod method)
	{
		return cvFindFundamentalMat(points1->ToCvMatPointer(), points2->ToCvMatPointer(), fundamental_matrix->ToCvMatPointer(), (int)method);
	}

	/// <summary>
	/// </summary>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <returns></returns>
	static int FindFundamentalMat(ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ fundamental_matrix)
	{
		return cvFindFundamentalMat(points1->ToCvMatPointer(), points2->ToCvMatPointer(), fundamental_matrix->ToCvMatPointer());
	}

	/// <summary>
	/// For each input point on one of images
	/// computes parameters of the corresponding
	/// epipolar line on the other image
	/// </summary>
	/// <param name="points"></param>
	/// <param name="which_image"></param>
	/// <param name="fundamental_matrix"></param>
	static void ComputeCorrespondEpilines(ManagedMat^ points, int which_image, ManagedMat^ fundamental_matrix, ManagedMat^ correspondent_lines)
	{
		cvComputeCorrespondEpilines(points->ToCvMatPointer(), which_image, fundamental_matrix->ToCvMatPointer(), correspondent_lines->ToCvMatPointer());
	}

	/// <summary>
	/// Triangulation functions
	/// </summary>
	/// <param name="projMatr1"></param>
	/// <param name="projMatr2"></param>
	/// <param name="projPoints1"></param>
	/// <param name="projPoints2"></param>
	static void TriangulatePoints(ManagedMat^ projMatr1, ManagedMat^ projMatr2, ManagedMat^ projPoints1, ManagedMat^ projPoints2, ManagedMat^ points4D)
	{
		cvTriangulatePoints(projMatr1->ToCvMatPointer(), projMatr2->ToCvMatPointer(), projPoints1->ToCvMatPointer(), projPoints2->ToCvMatPointer(), points4D->ToCvMatPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="F"></param>
	/// <param name="points1"></param>
	/// <param name="points2"></param>
	/// <param name="new_points1"></param>
	static void CorrectMatches(ManagedMat^ F, ManagedMat^ points1, ManagedMat^ points2, ManagedMat^ new_points1, ManagedMat^ new_points2)
	{
		cvCorrectMatches(F->ToCvMatPointer(), points1->ToCvMatPointer(), points2->ToCvMatPointer(), new_points1->ToCvMatPointer(), new_points2->ToCvMatPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="preset"></param>
	/// <returns></returns>
	static IntPtr CreateStereoBMState(StereoBlockMatchMode preset, int numberOfDisparities)
	{
		return IntPtr(cvCreateStereoBMState((int)preset, numberOfDisparities));
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static ManagedStereoBMState^ CreateStereoBMState(StereoBlockMatchMode preset)
	{
		return gcnew ManagedStereoBMState(cvCreateStereoBMState((int)preset), true);
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static ManagedStereoBMState^ CreateStereoBMState()
	{
		return gcnew ManagedStereoBMState(cvCreateStereoBMState(), true);
	}

	/// <summary>
	/// </summary>
	static void ReleaseStereoBMState(ManagedStereoBMState^% state)
	{
		CvStereoBMState* pStereoBMState = state->ToCvStereoBMStatePointer();
		cvReleaseStereoBMState(&pStereoBMState);
		state->m_pHandle = pStereoBMState;
	}

	/// <summary>
	/// </summary>
	/// <param name="left"></param>
	/// <param name="right"></param>
	/// <param name="disparity"></param>
	static void FindStereoCorrespondenceBM(ManagedArr^ left, ManagedArr^ right, ManagedArr^ disparity, ManagedStereoBMState^ state)
	{
		cvFindStereoCorrespondenceBM(left->ToCvArrPointer(), right->ToCvArrPointer(), disparity->ToCvArrPointer(), state->ToCvStereoBMStatePointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="numberOfDisparities"></param>
	/// <returns></returns>
	static ManagedStereoGCState^ CreateStereoGCState(int numberOfDisparities, int maxIters)
	{
		return gcnew ManagedStereoGCState(cvCreateStereoGCState(numberOfDisparities, maxIters), true);
	}

	/// <summary>
	/// </summary>
	static void ReleaseStereoGCState(ManagedStereoGCState^ state)
	{
		CvStereoGCState* pStereoGCState = state->ToCvStereoGCStatePointer();
		cvReleaseStereoGCState(&pStereoGCState);
		state->m_pHandle = pStereoGCState;
	}

	/// <summary>
	/// </summary>
	/// <param name="left"></param>
	/// <param name="right"></param>
	/// <param name="disparityLeft"></param>
	/// <param name="disparityRight"></param>
	/// <param name="state"></param>
	static void FindStereoCorrespondenceGC(ManagedArr^ left, ManagedArr^ right, ManagedArr^ disparityLeft, ManagedArr^ disparityRight, ManagedStereoGCState^ state, int useDisparityGuess)
	{
		cvFindStereoCorrespondenceGC(left->ToCvArrPointer(), right->ToCvArrPointer(), disparityLeft->ToCvArrPointer(), disparityRight->ToCvArrPointer(), state->ToCvStereoGCStatePointer(), useDisparityGuess);
	}

	/// <summary>
	/// </summary>
	/// <param name="left"></param>
	/// <param name="right"></param>
	/// <param name="disparityLeft"></param>
	/// <param name="disparityRight"></param>
	static void FindStereoCorrespondenceGC(ManagedArr^ left, ManagedArr^ right, ManagedArr^ disparityLeft, ManagedArr^ disparityRight, ManagedStereoGCState^ state)
	{
		cvFindStereoCorrespondenceGC(left->ToCvArrPointer(), right->ToCvArrPointer(), disparityLeft->ToCvArrPointer(), disparityRight->ToCvArrPointer(), state->ToCvStereoGCStatePointer());
	}

	/// <summary>
	/// Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix
	/// </summary>
	/// <param name="disparityImage"></param>
	/// <param name="_3dImage"></param>
	/// <param name="Q"></param>
	static void ReprojectImageTo3D(ManagedArr^ disparityImage, ManagedArr^ _3dImage, ManagedMat^ Q, bool handleMissingValues)
	{
		cvReprojectImageTo3D(disparityImage->ToCvArrPointer(), _3dImage->ToCvArrPointer(), Q->ToCvMatPointer(), (int)handleMissingValues);
	}

	/// <summary>
	/// Reprojects the computed disparity image to the 3D space using the specified 4x4 matrix
	/// </summary>
	/// <param name="disparityImage"></param>
	/// <param name="_3dImage"></param>
	static void ReprojectImageTo3D(ManagedArr^ disparityImage, ManagedArr^ _3dImage, ManagedMat^ Q)
	{
		cvReprojectImageTo3D(disparityImage->ToCvArrPointer(), _3dImage->ToCvArrPointer(), Q->ToCvMatPointer());
	}

//////////////////////////////////////////////////////////////////////////